How to use glob() to find files recursively?
pathlib.Path.rglob
Use pathlib.Path.rglob
from the the pathlib
module, which was introduced in Python 3.5.
from pathlib import Pathfor path in Path('src').rglob('*.c'): print(path.name)
If you don't want to use pathlib, use can use glob.glob('**/*.c')
, but don't forget to pass in the recursive
keyword parameter and it will use inordinate amount of time on large directories.
For cases where matching files beginning with a dot (.
); like files in the current directory or hidden files on Unix based system, use the os.walk
solution below.
os.walk
For older Python versions, use os.walk
to recursively walk a directory and fnmatch.filter
to match against a simple expression:
import fnmatchimport osmatches = []for root, dirnames, filenames in os.walk('src'): for filename in fnmatch.filter(filenames, '*.c'): matches.append(os.path.join(root, filename))
Similar to other solutions, but using fnmatch.fnmatch instead of glob, since os.walk already listed the filenames:
import os, fnmatchdef find_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 filenamefor filename in find_files('src', '*.c'): print 'Found C source:', filename
Also, using a generator alows you to process each file as it is found, instead of finding all the files and then processing them.
I've modified the glob module to support ** for recursive globbing, e.g:
>>> import glob2>>> all_header_files = glob2.glob('src/**/*.c')
https://github.com/miracle2k/python-glob2/
Useful when you want to provide your users with the ability to use the ** syntax, and thus os.walk() alone is not good enough.