for path in Path('src').rglob('*.c'): print(path.name)
glob.glob()
Если вы не хотите использовать pathlib, используйте glob.glob():
from glob import glob
for filename in glob('src/**/*.c', recursive=True): print(filename)
Для случаев, когда совпадающие файлы начинаются с точки (.); например, файлы в текущем каталоге или скрытые файлы в системе на базе Unix, используйте os.walk() решение ниже.
os.walk()
Для старых версий Python используйте os.walk() для рекурсивного обхода каталога и fnmatch.filter() для сопоставления с простым выражением:
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))
Эта версия также должна быть быстрее в зависимости от того, сколько у вас файлов, поскольку модуль pathlib имеет небольшие накладные расходы os.walk().
Ответ 2
Для python >= 3.5 вы можете использовать **, recursive=True, т.е.:
import glob for f in glob.glob('/path/**/*.c', recursive=True): print(f)
Если recursive имеет значение True (по умолчанию False), шаблон **будет соответствовать любым файлам и нулю или более directories и subdirectories. Если шаблону следует an os.sep, совпадают только каталоги и subdirectories.
Аналогично другим решениям, но с использованием fnmatch.fnmatch вместо glob, начиная с os.walk уже перечислил имена файлов:
import os, fnmatch
deffind_files(directory, pattern): for root, dirs, files in os.walk(directory): for basename in files: if fnmatch.fnmatch(basename, pattern): filename = os.path.join(root, basename) yield filename
for filename in find_files('src', '*.c'): print'Found C source:', filename
Кроме того, использование генератора позволяет обрабатывать каждый файл по мере его нахождения, вместо поиска всех файлов и последующей их обработки.
Ответ 4
Я модифицировал модуль glob для поддержки ** рекурсивного глобулирования, например: