这是我所拥有的:

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'))

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


当前回答

从Python 3.4开始,可以在新的pathlib模块中使用Path类之一的glob()方法,它支持**通配符。例如:

from pathlib import Path

for file_path in Path('src').glob('**/*.c'):
    print(file_path) # do whatever you need with these files

更新: 从Python 3.5开始,glob.glob()也支持相同的语法。

其他回答

下面是一个带有嵌套列表推导式的解决方案,os。Walk和简单的后缀匹配代替glob:

import os
cfiles = [os.path.join(root, filename)
          for root, dirnames, filenames in os.walk('src')
          for filename in filenames if filename.endswith('.c')]

它可以被压缩成一行代码:

import os;cfiles=[os.path.join(r,f) for r,d,fs in os.walk('src') for f in fs if f.endswith('.c')]

或概括为函数:

import os

def recursive_glob(rootdir='.', suffix=''):
    return [os.path.join(looproot, filename)
            for looproot, _, filenames in os.walk(rootdir)
            for filename in filenames if filename.endswith(suffix)]

cfiles = recursive_glob('src', '.c')

如果您确实需要完整的glob样式模式,您可以遵循Alex的和 Bruno的例子,使用fnmatch:

import fnmatch
import os

def recursive_glob(rootdir='.', pattern='*'):
    return [os.path.join(looproot, filename)
            for looproot, _, filenames in os.walk(rootdir)
            for filename in filenames
            if fnmatch.fnmatch(filename, pattern)]

cfiles = recursive_glob('src', '*.c')

另一种方法是只使用glob模块。只需给rglob方法添加一个起始基本目录和一个要匹配的模式,它就会返回一个匹配文件名的列表。

import glob
import os

def _getDirs(base):
    return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ]

def rglob(base, pattern):
    list = []
    list.extend(glob.glob(os.path.join(base,pattern)))
    dirs = _getDirs(base)
    if len(dirs):
        for d in dirs:
            list.extend(rglob(os.path.join(base,d), pattern))
    return list

如果文件位于远程文件系统上或归档文件中,则可以使用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文档。

我需要一个python 2的解决方案。在大目录上快速工作的X。 我得出了这个结论:

import subprocess
foundfiles= subprocess.check_output("ls src/*.c src/**/*.c", shell=True)
for foundfile in foundfiles.splitlines():
    print foundfile

注意,您可能需要一些异常处理,以防ls找不到任何匹配的文件。

我修改了glob模块,以支持**的递归配色,例如:

>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')

https://github.com/miracle2k/python-glob2/

当你想为你的用户提供使用**语法的能力时很有用,因此os.walk()本身不够好。