如何解决使用glob **根据递归参数匹配文件扩展名
我正在尝试使用全局模式匹配具有给定扩展名的文件。 glob函数(来自glob模块)具有参数“递归”,似乎应该打开或关闭搜索子目录。但是,只有在recursive = False的情况下,才能在当前目录中构造与当前类型的文件相匹配的glob模式,而在recursive = True的情况下,也不能在子目录中与该文件类型相匹配。
folder='C:\\test'
glob(folder+'**.ext',recursive=True) #fails to find any files
glob(folder+'\\**.ext',recursive=True) #fails to search subfolders
glob(folder+'\\**',recursive=True) #fails to filter by type
glob(folder+'\\**\\*.ext',recursive=False) #searches subfolders when it shouldn't
glob(folder+'**\\*.ext',recursive=True) #fails to search subfolders
基于文档
“ **”将匹配任何文件以及零个或多个目录
因此,我希望**的行为类似于*,但它也匹配斜杠。但是,它没有按预期运行(请参阅上面的前两个示例)。
为什么**不能按预期工作,并且有一种模式可以匹配某些文件类型,并且仅可以使用递归参数来打开或关闭递归?
解决方法
我认为您误解了recursive=True
的含义。它用于允许**
表示搜索可变深度的子目录-glob(folder+'\\**\\*.ext',recursive=True)
将在起始文件夹或其下方的任何位置找到任何*.ext
个文件。如果没有recursive=True
,将以正常方式解释**
,每个*
的含义是匹配除\
和{因此,{1}}等同于**
,换句话说,*
将搜索从起始文件夹向下精确到子目录一级的任何glob(folder+'\\**\\*.ext',recursive=False)
文件在起始文件夹本身或更深的子目录中。
究竟应该使用哪种取决于您要查找的内容-确实可能是您需要使用*.ext
语句在不同的情况下进行选择-但是没有用于的情况将if
与**
一起使用,因为在这种情况下,它等效于recursive=False
。
最可能有用的选项是:
*
glob(folder+'\\*.ext',recursive=False) # search in top folder only
glob(folder+'\\*\\*.ext',recursive=False) # search exactly one level down
glob(folder+'\\**\\*.ext',recursive=True) # search to arbitrary depth
可以省略,因为它是默认值。
如果要使用布尔选项在两个选项之间进行选择,则始终可以编写自己的包装函数,例如:
,recursive=False
(在类似Unix的操作系统中,请阅读上文def myglob(folder,pattern,subdirs=False):
if subdirs:
return glob(f'{folder}\\**\\{pattern}',recursive=True)
else
return glob(f'{folder}\\{pattern}')
print(myglob(folder,'*.ext',subdirs=False))
print(myglob(folder,subdirs=True))
print(myglob(folder,'*.ext')) # same as subdirs=False in this example
的{{1}}。)
全局'**'的操作
可以在here中找到glob源代码。除注释外,“ **”仅出现在_isrecursive函数中:
def _isrecursive(pattern):
if isinstance(pattern,bytes):
return pattern == b'**'
else:
return pattern == '**'
由于_isrecursive函数使用相等运算符检查'',因此''仅在完整的'pattern'时才按预期运行。 _isrecursive函数在源代码中被调用4次,对整个glob调用一次,对“ basename”调用3次,定义为:
dirname,basename = os.path.split(pathname)
这是递归调用,一次将路径的尾部分开,每次,基名都是斜杠后面的所有内容(在技术上是os.sep,对于Windows或POSIX,它是\)。这意味着,为了使“ **”按所述方式运行,它不得与除斜杠之外的其他任何东西相邻。
如果递归未明确设置为True,则'**'='*'+'*'='*',因为'*'匹配0个或多个非斜杠字符。
匹配扩展
由于'**'的工作方式,必须使用它表示整个glob的级别。由于r'folder \ ** \ *。ext' 表示 0个或更多级别,因此将匹配“ folder”以及子文件夹中的文件。但是,如果未将递归设置为true,则此模式将仅匹配子文件夹第一级中的文件。
'**。ext'将不起作用,因为'**'并不孤单。剩下以下选项:
-
使用其他库(例如os.walk,pathlib.glob等)
-
[f for f in glob(folder+'\\**',recursive=subdirs) if f.endswith('.ext')]
-
glob(folder+('\\**' if subdirs else '')+'\\*.ext,recursive=True)
或等效地,
if recursive: glob(folder+'\\**\\*.ext',recursive=True) else: glob(folder+'\\*.ext')
-
glob(folder+'\\..\\**\\*.ext',recursive=subdirs) #not recommended since it will also match files in sibling folders
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。