Mam katalog z bandą plików wewnątrz: eee2314
, asd3442
... a eph
.
Chcę wykluczyć wszystkie pliki, które zaczynają eph
się od glob
funkcji.
Jak mogę to zrobić?
Reguły wzorców dla glob nie są wyrażeniami regularnymi. Zamiast tego stosują się do standardowych reguł rozwijania ścieżek w systemie Unix. Jest tylko kilka znaków specjalnych: dwa różne symbole wieloznaczne i obsługiwane są zakresy znaków [z pymotw: glob - dopasowanie wzorca nazwy pliku ].
Możesz więc wykluczyć niektóre pliki z wzorami.
Na przykład, aby wykluczyć pliki manifestów (pliki zaczynające się od _
) z glob, możesz użyć:
files = glob.glob('files_path/[!_]*')
eph
ale mogą zaczynać się od czegoś innego.[!e][!p][!h]
odfiltruje pliki zaczynające sięeee
na przykład od.Możesz odliczyć zestawy:
set(glob("*")) - set(glob("eph*"))
źródło
set(glob("*")) - set(glob("eph*"))
(i zauważ * na końcu „eph *”)list(set(glob("*")) - set(glob("eph")))
Nie możesz wykluczyć wzorców za pomocą
glob
funkcji, globy pozwalają tylko na włączanie wzorców. Składnia globbingu jest bardzo ograniczona (nawet[!..]
klasa znaków musi pasować do znaku, więc jest to wzorzec włączenia dla każdego znaku, którego nie ma w klasie).Będziesz musiał wykonać własne filtrowanie; rozumienie listy zwykle dobrze działa tutaj:
files = [fn for fn in glob('somepath/*.txt') if not os.path.basename(fn).startswith('eph')]
źródło
iglob
tutaj, aby uniknąć przechowywania pełnej listy w pamięciiglob
tworzy listy ; wszystko co robisz to leniwie oceniasz filtr. Nie pomoże to w zmniejszeniu zużycia pamięci.os.listdir()
wynik jest przechowywany w pamięci podczas iteracji. Alesomepath/*.txt
musi czytać wszystkie nazwy plików w jednym katalogu w pamięci, a następnie zredukować tę listę do tylko tych, które pasują.glob.glob(x) = list(glob.iglob(x))
. Niewielkie koszty, ale dobrze wiedzieć.Spóźniony do gry, ale alternatywnie możesz po prostu zastosować Pythona
filter
do wynikuglob
:files = glob.iglob('your_path_here') files_i_care_about = filter(lambda x: not x.startswith("eph"), files)
lub zastąpienie lambdy odpowiednim wyszukiwaniem wyrażeń regularnych itp.
EDYCJA: Właśnie zdałem sobie sprawę, że jeśli używasz pełnych ścieżek
startswith
, nie zadziała, więc potrzebujesz wyrażenia regularnegoIn [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']
źródło
Co powiesz na pominięcie konkretnego pliku podczas iteracji po wszystkich plikach w folderze! Poniższy kod pomija wszystkie pliki Excela zaczynające się od „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)
W ten sposób możesz użyć bardziej złożonych wzorców regex, aby uwzględnić / wykluczyć określony zestaw plików w folderze.
źródło
Porównaj z
glob
, polecampathlib
, filtr jeden wzorzec jest bardzo prosty.from pathlib import Path p = Path(YOUR_PATH) filtered = [x for x in p.glob("**/*") if not x.name.startswith("eph")]
a jeśli chcesz filtrować bardziej złożony wzorzec, możesz zdefiniować funkcję, która to zrobi, tak jak:
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)]
użyj tego kodu, możesz filtrować wszystkie pliki, które zaczynają się od
eph
lub zaczynają się odepi
.źródło
Bardziej ogólnie, aby wykluczyć pliki, które nie są zgodne z niektórymi wyrażeniami regularnymi powłoki, możesz użyć modułu
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)
Powyższe najpierw wygeneruje listę z podanej ścieżki, a następnie wyskoczy pliki, które nie spełnią wyrażenia regularnego z żądanym ograniczeniem.
źródło
Jak wspomniano w akceptowanej odpowiedzi, nie możesz wykluczyć wzorców za pomocą glob, więc poniżej przedstawiono metodę filtrowania wyniku glob.
Przyjęta odpowiedź jest prawdopodobnie najlepszym Pythonowym sposobem robienia rzeczy, ale jeśli uważasz, że listy składane wyglądają trochę brzydko i chcesz, aby Twój kod i tak był maksymalnie numpythonic (tak jak ja), możesz to zrobić (ale pamiętaj, że jest to prawdopodobnie mniej wydajne niż metoda rozumienia listy):
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*"))
(W moim przypadku miałem kilka ramek obrazów, ramek odchylenia i płaskich ramek w jednym katalogu i chciałem tylko ramki obrazów)
źródło
Jeśli pozycja znaku nie jest ważna, to znaczy na przykład, aby wykluczyć pliki manifestów (gdziekolwiek zostanie znaleziony
_
) za pomocąglob
ire
- operacji wyrażeń regularnych , możesz użyć:import glob import re for file in glob.glob('*.txt'): if re.match(r'.*\_.*', file): continue else: print(file)
Lub w bardziej elegancki sposób -
list comprehension
filtered = [f for f in glob.glob('*.txt') if not re.match(r'.*\_.*', f)] for mach in filtered: print(mach)
źródło
Możesz użyć poniższej metody:
# 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.
źródło