问:
这就是我所拥有的:
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'))
但这显然是有限且笨重的。
答1:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
pathlib.Path.rglob
使用 Python 3.5 中引入的 pathlib 模块中的 pathlib.Path.rglob。
from pathlib import Path
for path in Path('src').rglob('*.c'):
print(path.name)
如果不想使用 pathlib,可以使用 glob.glob(‘**/*.c’),但不要忘记传入 recursive 关键字参数,它会在大型目录上占用过多的时间。
对于匹配文件以点 (.) 开头的情况;如当前目录中的文件或基于 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))
对于早于 2.2 的 Python,有 os.path.walk(),它比 os.walk() 更容易使用
@gnibbler 我知道这是一条旧评论,但我的评论只是为了让人们知道 os.path.walk() 已被弃用并已在 Python 3 中删除。
@DevC 可能适用于这个问题中提出的特定情况,但很容易想象有人想要使用它来处理诸如 'a*.c' 等查询,所以我认为值得保留当前有点慢的答案。
对于它的价值,在我的情况下,使用 glob 查找 10,000 多个文件比使用 os.walk 慢得多,因此出于这个原因,我选择了后一种解决方案。
对于 python 3.4,pathlib.Path('src').glob('**/*.c') 应该可以工作。
答2:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
对于 python >= 3.5 你可以使用 **, recursive=True :
import glob
for f in glob.glob('/path/**/*.c', recursive=True):
print(f)
如果 recursive 为 True,则模式 ** 将匹配任何文件以及零个或多个目录和子目录。如果模式后跟 os.sep,则只有目录和子目录匹配。
Python 3.6 Demo
这比 pathlib.Path('./path/').glob('*/') 更好,因为它在大小为 0 的文件夹中也是如此
在 Python 3.9.1 中,recursive 默认设置为 False。
在 Python 3.8.* 中,recursive 也默认设置为 False。
答3:
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
与其他解决方案类似,但使用 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
此外,使用生成器可以让您在找到每个文件时对其进行处理,而不是查找所有文件然后处理它们。
答4:
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
我已经修改了 glob 模块以支持 ** 进行递归通配,例如:
>>> import glob2
>>> all_header_files = glob2.glob('src/**/*.c')
https://github.com/miracle2k/python-glob2/
当您希望为用户提供使用 ** 语法的能力时很有用,因此单独使用 os.walk() 还不够好。
我们可以在它找到第一个匹配项后让它停止吗?也许可以将它用作生成器,而不是让它返回每个可能结果的列表?另外,这是 DFS 还是 BFS?我认为我更喜欢 BFS,以便首先找到根附近的文件。 +1 用于制作此模块并在 GitHub/pip 上提供。
** 语法被添加到 Python 3.5 的官方 glob 模块中。
@ArtOfWarfare 好的,好的。这对于 < 3.5 仍然有用。
要使用带有官方 glob 模块的 ** 激活递归通配符,请执行以下操作:glob(path, recursive=True)
答5:
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
从 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() 也支持相同的语法。
确实,it will be in Python 3.5。它应该在 Python 3.4 中已经如此,但omitted by mistake。
此语法现在是 supported by glob.glob() as of Python 3.5。
请注意,您还可以组合使用 pathlib.PurePath.relative_to 来获取相对路径。有关更多上下文,请参见 my answer here。
答6:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
import os
import fnmatch
def recursive_glob(treeroot, pattern):
results = []
for base, dirs, files in os.walk(treeroot):
goodfiles = fnmatch.filter(files, pattern)
results.extend(os.path.join(base, f) for f in goodfiles)
return results
fnmatch 为您提供与 glob 完全相同的模式,因此这确实是 glob.glob 的绝佳替代品,具有非常接近的语义。一个迭代版本(例如生成器),IOW 替代 glob.iglob,是一种微不足道的适应(只是 yield 中间结果,而不是 extend 在最后返回单个结果列表)。
您如何看待我在编辑中建议的使用 recursive_glob(pattern, treeroot='.')?这样,它可以被称为 recursive_glob('*.txt') 并且直观地匹配 glob 的语法。
@ChrisRedford,无论哪种方式,我都认为这是一个很小的问题。就目前而言,它匹配 fnmatch.filter 的“文件然后模式”参数顺序,这与匹配单参数 glob.glob 的可能性大致相同。
答7:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
您需要使用 os.walk 来收集符合您的条件的文件名。例如:
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))
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
答8:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
这是一个包含嵌套列表推导、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')
答9:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
考虑 pathlib.rglob()。
这就像在给定的相对模式前添加“**/”调用 Path.glob():
import pathlib
for p in pathlib.Path("src").rglob("*.c"):
print(p)
另请参阅此处 @taleinat 的相关 post 和其他地方的类似 post。
答10:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
import os, glob
for each in glob.glob('path/**/*.c', recursive=True):
print(f'Name with path: {each} \nName without path: {os.path.basename(each)}')
glob.glob(‘*.c’) :匹配当前目录中所有以 .c 结尾的文件
glob.glob(‘/.c’) : 同 1
glob.glob(‘**/*.c’) :仅匹配直接子目录中所有以 .c 结尾的文件,但不匹配当前目录中的所有文件
glob.glob(‘*.c’,recursive=True) : 同 1
glob.glob(‘/.c’,recursive=True) : 同 3
glob.glob(‘**/*.c’,recursive=True) :匹配当前目录和所有子目录中所有以.c结尾的文件
答11:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
最近我不得不用扩展名 .jpg 恢复我的照片。我运行 photorec 并恢复了 4579 个目录,其中包含 220 万个文件,扩展名种类繁多。使用下面的脚本,我能够在几分钟内选择 50133 个具有 .jpg 扩展名的文件:
#!/usr/binenv python2.7
import glob
import shutil
import os
src_dir = "/home/mustafa/Masaüstü/yedek"
dst_dir = "/home/mustafa/Genel/media"
for mediafile in glob.iglob(os.path.join(src_dir, "*", "*.jpg")): #"*" is for subdirectory
shutil.copy(mediafile, dst_dir)
原文链接:https://www.huntsbot.com/qa/82ZK/how-to-use-glob-to-find-files-recursively?lang=zh_CN&from=csdn
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com