如何在Python中使用glob.glob模块search子文件夹?

我想打开一个文件夹中的一系列子文件夹,并find一些文本文件,并打印文本文件的一些行。 我正在使用这个:

configfiles = glob.glob('C:/Users/sam/Desktop/file1/*.txt') 

但是这也不能访问子文件夹。 有谁知道我可以如何使用相同的命令来访问子文件夹?

在Python 3.5和更新的版本中,使用新的recursion**/function:

 configfiles = glob.glob('C:/Users/sam/Desktop/file1/**/*.txt', recursive=True) 

当设置recursive**后跟一个path分隔符匹配0个或多个子目录。

在较早的Python版本中, glob.glob()不能recursion地列出子目录中的文件。

在这种情况下,我会使用os.walk()fnmatch.filter()相结合:

 import os import fnmatch path = 'C:/Users/sam/Desktop/file1' configfiles = [os.path.join(dirpath, f) for dirpath, dirnames, files in os.walk(path) for f in fnmatch.filter(files, '*.txt')] 

这将recursion地遍历您的目录,并返回所有绝对path名匹配的.txt文件。 在这个特定的情况下, fnmatch.filter()可能是矫枉过正的,你也可以使用.endswith()testing:

 import os path = 'C:/Users/sam/Desktop/file1' configfiles = [os.path.join(dirpath, f) for dirpath, dirnames, files in os.walk(path) for f in files if f.endswith('.txt')] 

glob2包支持通配符,速度相当快

 code = ''' import glob2 glob2.glob("files/*/**") ''' timeit.timeit(code, number=1) 

在我的笔记本电脑上,大约需要2秒来匹配> 60,000个文件path 。

要查找直接子目录中的文件,请执行以下操作:

 configfiles = glob.glob(r'C:\Users\sam\Desktop\*\*.txt') 

对于遍历所有子目录的recursion版本,您可以使用**并从Python 3.5开始传递recursive=True

 configfiles = glob.glob(r'C:\Users\sam\Desktop\**\*.txt', recursive=True) 

这两个函数调用返回列表。 你可以使用glob.iglob()来逐一返回path。 或者使用pathlib

 from pathlib import Path path = Path(r'C:\Users\sam\Desktop') txt_files_only_subdirs = path.glob('*/*.txt') txt_files_all_recursively = path.rglob('*.txt') # including the current dir 

这两个方法都会返回迭代器(您可以逐个获取path)。

你可以使用Formic Python 2.6

 import formic fileset = formic.FileSet(include="**/*.txt", directory="C:/Users/sam/Desktop/") 

披露 – 我是这个软件包的作者。

这是一个修改后的版本,可以在不使用glob2情况下启用glob.glob类似的function。

 def find_files(directory, pattern='*'): if not os.path.exists(directory): raise ValueError("Directory not found {}".format(directory)) matches = [] for root, dirnames, filenames in os.walk(directory): for filename in filenames: full_path = os.path.join(root, filename) if fnmatch.filter([full_path], pattern): matches.append(os.path.join(root, filename)) return matches 

所以,如果你有以下的目录结构

 tests/files ├── a0 │  ├── a0.txt │  ├── a0.yaml │  └── b0 │  ├── b0.yaml │  └── b00.yaml └── a1 

你可以做这样的事情

 files = utils.find_files('tests/files','**/b0/b*.yaml') > ['tests/files/a0/b0/b0.yaml', 'tests/files/a0/b0/b00.yaml'] 

很多fnmatch模式匹配整个文件名本身,而不仅仅是文件名。

configfiles = glob.glob('C:/Users/sam/Desktop/**/*.txt")

不适用于所有情况,而是使用glob2

 configfiles = glob2.glob('C:/Users/sam/Desktop/**/*.txt") 

如果你可以安装glob2包…

 import glob2 filenames = glob2.glob("C:\\top_directory\\**\\*.ext") # Where ext is a specific file extension folders = glob2.glob("C:\\top_directory\\**\\") 

所有文件名和文件夹:

 all_ff = glob2.glob("C:\\top_directory\\**\\**") 

正如Martijn所指出的,glob只能通过Python 3.5中引入的**运算符来实现。 由于OP明确要求glob模块,下面将返回一个惰性评估迭代器,其行为相似

 import os, glob, itertools configfiles = itertools.chain.from_iterable(glob.iglob(os.path.join(root,'*.txt')) for root, dirs, files in os.walk('C:/Users/sam/Desktop/file1/')) 

请注意,尽pipe这种方法只能在configfiles上迭代一次。 如果你需要一个可以在多个操作中使用的configfiles列表,你将不得不使用list(configfiles)来明确地创build它。

如果你正在运行Python 3.4+,你可以使用pathlib模块。 Path.glob()方法支持**模式,这意味着“这个目录和所有子目录,recursion”。 它返回一个生成器生成所有匹配文件的Path对象。

 from pathlib import Path configfiles = Path("C:/Users/sam/Desktop/file1/").glob("**/*.txt")