这是我所拥有的:

glob(os.path.join('src','*.c'))

但是我想搜索src的子文件夹。这样做是可行的:

glob(os.path.join('src','*.c'))
glob(os.path.join('src','*','*.c'))
glob(os.path.join('src','*','*','*.c'))
glob(os.path.join('src','*','*','*','*.c'))

但这显然是有限和笨拙的。


当前回答

类似于其他解决方案,但使用fnmatch。Fnmatch而不是glob,因为os。Walk已经列出了文件名:

import os, fnmatch


def 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 filename


for filename in find_files('src', '*.c'):
    print 'Found C source:', filename

此外,使用生成器允许您在找到每个文件时处理它,而不是找到所有文件然后处理它们。

其他回答

如果文件位于远程文件系统上或归档文件中,则可以使用fspecabstractfilesystem类的实现。例如,要列出一个zipfile中的所有文件:

from fsspec.implementations.zip import ZipFileSystem
fs = ZipFileSystem("/tmp/test.zip")
fs.glob("/**")  # equivalent: fs.find("/")

或者列出公共S3桶中的所有文件:

from s3fs import S3FileSystem
fs_s3 = S3FileSystem(anon=True)
fs_s3.glob("noaa-goes16/ABI-L1b-RadF/2020/045/**")  # or use fs_s3.find

你也可以将它用于本地文件系统,如果你的实现应该是文件系统不可知的,这可能会很有趣:

from fsspec.implementations.local import LocalFileSystem
fs = LocalFileSystem()
fs.glob("/tmp/test/**")

其他实现包括谷歌云,Github, SFTP/SSH, Dropbox和Azure。具体操作请参见fspec API文档。

你需要使用操作系统。行走以收集符合条件的文件名。例如:

import os
cfiles = []
for root, dirs, files in os.walk('src'):
  for file in files:
    if file.endswith('.c'):
      cfiles.append(os.path.join(root, file))

下面是我的解决方案,使用列表理解在一个目录和所有子目录中递归地搜索多个文件扩展名:

import os, glob

def _globrec(path, *exts):
""" Glob recursively a directory and all subdirectories for multiple file extensions 
    Note: Glob is case-insensitive, i. e. for '\*.jpg' you will get files ending
    with .jpg and .JPG

    Parameters
    ----------
    path : str
        A directory name
    exts : tuple
        File extensions to glob for

    Returns
    -------
    files : list
        list of files matching extensions in exts in path and subfolders

    """
    dirs = [a[0] for a in os.walk(path)]
    f_filter = [d+e for d in dirs for e in exts]    
    return [f for files in [glob.iglob(files) for files in f_filter] for f in files]

my_pictures = _globrec(r'C:\Temp', '\*.jpg','\*.bmp','\*.png','\*.gif')
for f in my_pictures:
    print f

除了建议的答案,你还可以用一些惰性生成和列表理解魔法来做到这一点:

import os, glob, itertools

results = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.c'))
                                               for root, dirs, files in os.walk('src'))

for f in results: print(f)

除了适合一行并避免内存中不必要的列表之外,这还有一个很好的副作用,你可以以类似于**操作符的方式使用它,例如,你可以使用os.path。Join (root, 'some/path/*.c')以获取SRC所有子目录下具有此结构的所有。c文件。

考虑pathlib.rglob()。

这就像调用Path.glob(),在给定的相对模式前添加“**/”:

import pathlib


for p in pathlib.Path("src").rglob("*.c"):
    print(p)

也可以在这里看到@taleinat的相关帖子和其他地方的类似帖子。