Ho una directory con un gruppo di file all'interno: eee2314
, asd3442
... e eph
.
Voglio escludere tutti i file che iniziano eph
con la glob
funzione.
Come posso farlo?
Ho una directory con un gruppo di file all'interno: eee2314
, asd3442
... e eph
.
Voglio escludere tutti i file che iniziano eph
con la glob
funzione.
Come posso farlo?
Risposte:
Le regole del modello per glob non sono espressioni regolari. Invece, seguono le regole standard di espansione del percorso Unix. Ci sono solo pochi caratteri speciali: sono supportati due diversi caratteri jolly e intervalli di caratteri [da glob ].
Quindi puoi escludere alcuni file con modelli.
Ad esempio, per escludere file manifesti (file che iniziano con _
) con glob, puoi usare:
files = glob.glob('files_path/[!_]*')
eph
ma possono iniziare con qualsiasi altra cosa. [!e][!p][!h]
filtrerà i file che iniziano con, eee
ad esempio.
Puoi detrarre i set:
set(glob("*")) - set(glob("eph*"))
set(glob("*")) - set(glob("eph*"))
(e nota * alla fine di "eph *")
list(set(glob("*")) - set(glob("eph")))
Non puoi escludere modelli con la glob
funzione, i glob consentono solo modelli di inclusione . La sintassi del globbing è molto limitata (anche una [!..]
classe di caratteri deve corrispondere a un carattere, quindi è un modello di inclusione per ogni carattere che non è nella classe).
Dovrai fare il tuo filtro; una comprensione dell'elenco di solito funziona bene qui:
files = [fn for fn in glob('somepath/*.txt')
if not os.path.basename(fn).startswith('eph')]
iglob
qui per evitare di memorizzare l'elenco completo in memoria
iglob
produce comunque liste ; tutto quello che fai è valutare pigramente il filtro. Non aiuterà a ridurre l'impronta di memoria.
os.listdir()
risultato viene mantenuto in memoria mentre iterate. Ma somepath/*.txt
deve leggere tutti i nomi di file in una directory in memoria, quindi ridurre quell'elenco solo a quelli che corrispondono.
glob.glob(x) = list(glob.iglob(x))
. Non un granché ma comunque buono a sapersi.
In ritardo al gioco ma in alternativa potresti semplicemente applicare un pitone filter
al risultato di glob
:
files = glob.iglob('your_path_here')
files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
o sostituendo il lambda con una ricerca regex appropriata, ecc ...
EDIT: Mi sono appena reso conto che se stai usando percorsi completi startswith
, non funzionerà, quindi avresti bisogno di una regex
In [10]: a
Out[10]: ['/some/path/foo', 'some/path/bar', 'some/path/eph_thing']
In [11]: filter(lambda x: not re.search('/eph', x), a)
Out[11]: ['/some/path/foo', 'some/path/bar']
Che ne dici di saltare il file particolare durante l'iterazione su tutti i file nella cartella! Il codice seguente salterà tutti i file Excel che iniziano con "eph"
import glob
import re
for file in glob.glob('*.xlsx'):
if re.match('eph.*\.xlsx',file):
continue
else:
#do your stuff here
print(file)
In questo modo puoi utilizzare schemi regex più complessi per includere / escludere un particolare insieme di file in una cartella.
Confronta con glob
, mi raccomando pathlib
, filtrare un pattern è molto semplice.
from pathlib import Path
p = Path(YOUR_PATH)
filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
e se vuoi filtrare pattern più complessi, puoi definire una funzione per farlo, proprio come:
def not_in_pattern(x):
return (not x.name.startswith("eph")) and not x.name.startswith("epi")
filtered = [x for x in p.glob("**/*") if not_in_pattern(x)]
usa quel codice, puoi filtrare tutti i file che iniziano con eph
o iniziano con epi
.
Più in generale, per escludere file che non rispettano alcune espressioni regolari di shell, potresti usare module fnmatch
:
import fnmatch
file_list = glob('somepath')
for ind, ii in enumerate(file_list):
if not fnmatch.fnmatch(ii, 'bash_regexp_with_exclude'):
file_list.pop(ind)
Quanto sopra genererà prima un elenco da un determinato percorso e successivamente verranno visualizzati i file che non soddisfano l'espressione regolare con il vincolo desiderato.
Come menzionato dalla risposta accettata, non è possibile escludere pattern con glob, quindi il seguente è un metodo per filtrare il risultato glob.
La risposta accettata è probabilmente il miglior modo pitonico per fare le cose, ma se pensi che la comprensione delle liste sembri un po 'brutta e vuoi comunque rendere il tuo codice massimamente numpitonico (come ho fatto io) allora puoi farlo (ma nota che questo è probabilmente meno efficiente rispetto al metodo di comprensione delle liste):
import glob
data_files = glob.glob("path_to_files/*.fits")
light_files = np.setdiff1d( data_files, glob.glob("*BIAS*"))
light_files = np.setdiff1d(light_files, glob.glob("*FLAT*"))
(Nel mio caso, avevo alcuni frame di immagine, frame bias e frame piatti tutti in una directory e volevo solo i frame dell'immagine)
Se la posizione del carattere non è importante, ad esempio per escludere file manifest (ovunque si trovi _
) con glob
e re
- operazioni di espressioni regolari , puoi usare:
import glob
import re
for file in glob.glob('*.txt'):
if re.match(r'.*\_.*', file):
continue
else:
print(file)
O con in un modo più elegante - list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)]
for mach in filtered:
print(mach)
Puoi usare il metodo seguente:
# Get all the files
allFiles = glob.glob("*")
# Files starting with eph
ephFiles = glob.glob("eph*")
# Files which doesnt start with eph
noephFiles = []
for file in allFiles:
if file not in ephFiles:
noephFiles.append(file)
# noepchFiles has all the file which doesnt start with eph.
Thank you.