Python 3.5+
Ponieważ korzystasz z nowego Pythona, powinieneś używać pathlib.Path.rglob
z pathlib
modułu.
from pathlib import Path
for path in Path('src').rglob('*.c'):
print(path.name)
Jeśli nie chcesz używać pathlib, po prostu użyj glob.glob
, ale nie zapomnij podać recursive
parametru słowa kluczowego.
W przypadkach, gdy pasujące pliki zaczynają się od kropki (.); jak pliki w bieżącym katalogu lub pliki ukryte w systemie uniksowym, skorzystaj z os.walk
poniższego rozwiązania.
Starsze wersje Pythona
W przypadku starszych wersji Python użyj os.walk
rekurencyjnie chodzić po katalogu i fnmatch.filter
dopasować do prostego wyrażenia:
import fnmatch
import os
matches = []
for root, dirnames, filenames in os.walk('src'):
for filename in fnmatch.filter(filenames, '*.c'):
matches.append(os.path.join(root, filename))
os.path.walk()
nieco bardziej kłopotliwy w użyciu niżos.walk()
os.path.walk()
jest on przestarzały i został usunięty w Pythonie 3.pathlib.Path('src').glob('**/*.c')
powinien działać.Podobne do innych rozwiązań, ale z użyciem fnmatch.fnmatch zamiast glob, ponieważ os.walk już podał nazwy plików:
Ponadto użycie generatora pozwala przetwarzać każdy znaleziony plik zamiast znajdować wszystkie pliki, a następnie je przetwarzać.
źródło
reduce(lambda x, y: x+y, map(lambda (r,_,x):map(lambda f: r+'/'+f, filter(lambda f: fnmatch.fnmatch(f, pattern), x)), os.walk('src/webapp/test_scripts')))
(os.path.join(root,filename) for root, dirs, files in os.walk(directory) for filename in files if fnmatch.fnmatch(filename, pattern))
Zmodyfikowałem moduł glob, aby obsługiwał ** dla globowania rekurencyjnego, np .:
https://github.com/miracle2k/python-glob2/
Przydatne, gdy chcesz zapewnić użytkownikom możliwość korzystania ze składni **, a zatem sama os.walk () nie jest wystarczająco dobra.
źródło
**
pomocą oficjalnego modułu glob, wykonaj:glob(path, recursive=True)
Począwszy od Pythona 3.4, można użyć
glob()
metody jednej zPath
klas w nowym module pathlib , który obsługuje**
symbole wieloznaczne. Na przykład:Aktualizacja: Począwszy od Python 3.5, ta sama składnia jest również obsługiwana przez
glob.glob()
.źródło
fnmatch
daje dokładnie takie same wzory jakglob
, więc jest to naprawdę doskonały zamiennik dlaglob.glob
bardzo ścisłej semantyki. Wersja iteracyjna (np. Generator), zastępująca IOWglob.iglob
, jest trywialną adaptacją (tylkoyield
pośrednie wyniki na bieżąco, zamiastextend
wprowadzania pojedynczej listy wyników do powrotu na końcu).źródło
recursive_glob(pattern, treeroot='.')
jak zasugerowałem w mojej edycji? W ten sposób można go na przykład wywołaćrecursive_glob('*.txt')
i intuicyjnie dopasować składnięglob
.fnmatch.filter
, co jest mniej więcej tak przydatne, jak możliwość dopasowania pojedynczego argumentuglob.glob
.Dla python> = 3,5 można użyć
**
,recursive=True
:Próbny
źródło
Będziesz chciał użyć
os.walk
do zbierania nazw plików, które spełniają Twoje kryteria. Na przykład:źródło
Oto rozwiązanie z listami zagnieżdżonymi
os.walk
i prostym dopasowaniem sufiksu zamiastglob
:Można go skompresować do jednej linijki:
lub uogólnione jako funkcja:
Jeśli potrzebujesz pełnych
glob
wzorów, możesz pójść za przykładem Alexa i Bruno i użyćfnmatch
:źródło
Ostatnio musiałem odzyskać moje zdjęcia z rozszerzeniem .jpg. Uruchomiłem photorec i odzyskałem 4579 katalogów 2,2 miliona plików, mając ogromną różnorodność rozszerzeń. Za pomocą poniższego skryptu byłem w stanie wybrać 50133 plików z rozszerzeniem .jpg w ciągu kilku minut:
źródło
Zastanów się
pathlib.rglob()
.Zobacz także powiązany post @ taleinat tutaj i podobny post gdzie indziej.
źródło
Johan i Bruno zapewniają doskonałe rozwiązania dotyczące minimalnych wymagań, jak podano. Właśnie wydałem Formic, który implementuje Ant FileSet i Globs, które mogą obsłużyć ten i bardziej skomplikowane scenariusze. Realizacja twojego wymagania to:
źródło
w oparciu o inne odpowiedzi jest to moja bieżąca działająca implementacja, która pobiera zagnieżdżone pliki xml w katalogu głównym:
Naprawdę dobrze się bawię z Pythonem :)
źródło
Kolejny sposób, aby to zrobić za pomocą samego modułu glob. Po prostu zapisz metodę rglob początkowym katalogiem podstawowym i pasującym wzorcem, a ona zwróci listę pasujących nazw plików.
źródło
Dla python 3.5 i nowszych
dalej możesz potrzebować
źródło
/**
działa dla mnie w ten sposób:file_names_array = glob.glob('src/**/*.c', recursive=True)
Lub ze zrozumieniem listy:
źródło
Właśnie to zrobiłem .. wydrukuje pliki i katalog w sposób hierarchiczny
Ale nie użyłem fnmatcha ani chodzenia
źródło
Ten używa fnmatch lub wyrażenia regularnego:
źródło
Oprócz sugerowanych odpowiedzi możesz to zrobić za pomocą leniwej generacji i magii ze zrozumieniem listy:
Poza dopasowaniem do jednej linii i unikaniem niepotrzebnych list w pamięci, ma to również fajny efekt uboczny, że możesz go użyć w sposób podobny do operatora **, np. Możesz użyć
os.path.join(root, 'some/path/*.c')
, aby uzyskać wszystkie pliki .c we wszystkich podkatalogi src, które mają tę strukturę.źródło
To jest działający kod w Pythonie 2.7. W ramach mojej pracy devops musiałem napisać skrypt, który przeniósłby pliki konfiguracyjne oznaczone live-appName.properties do appName.properties. Mogą istnieć inne pliki rozszerzeń, takie jak live-appName.xml.
Poniżej znajduje się działający kod, który znajduje pliki w podanych katalogach (poziom zagnieżdżony), a następnie zmienia nazwy (przenosi) na wymaganą nazwę pliku
Ta funkcja jest wywoływana ze skryptu głównego
Mam nadzieję, że to pomoże komuś zmagać się z podobnymi problemami.
źródło
Uproszczona wersja odpowiedzi Johana Dahlina, bez fnmatcha .
źródło
Oto moje rozwiązanie wykorzystujące funkcję list list do wyszukiwania wielu rozszerzeń plików rekurencyjnie w katalogu i wszystkich podkatalogach:
źródło
źródło
Zmodyfikowałem najwyższą odpowiedź w tym poście .. i niedawno utworzyłem ten skrypt, który będzie przechodził przez wszystkie pliki w danym katalogu (searchdir) i podkatalogach pod nim ... i drukuje nazwę pliku, katalog główny, datę modyfikacji / utworzenia i rozmiar.
Mam nadzieję, że to pomoże komuś ... i może przejść do katalogu i uzyskać fileinfo.
źródło
Oto rozwiązanie, które dopasuje wzór do pełnej ścieżki, a nie tylko podstawowej nazwy pliku.
To używa
fnmatch.translate
do konwertowania wzorca globalnego na wyrażenie regularne, które jest następnie porównywane z pełną ścieżką każdego pliku znalezionego podczas przechodzenia przez katalog.re.IGNORECASE
jest opcjonalny, ale pożądany w systemie Windows, ponieważ sam system plików nie rozróżnia wielkości liter. (Nie zawracałem sobie głowy kompilowaniem wyrażenia regularnego, ponieważ dokumenty wskazują, że powinien on być buforowany wewnętrznie).źródło
Potrzebowałem rozwiązania dla Pythona 2.x, które działa szybko w dużych katalogach.
Kończę z tym:
Pamiętaj, że możesz potrzebować obsługi wyjątków na wypadek, gdyby
ls
nie znalazł pasującego pliku.źródło
ls src/**/*.c
działa tylko wtedy, gdy włączona jest opcja globstar (shopt -s globstar
) - szczegółowe informacje znajdują się w tej odpowiedzi .