包含子目录的模式的Python fnmatch筛选器

包含子目录的模式的Python fnmatch筛选器,python,path,Python,Path,我正在尝试使用fnmatch筛选器查找给定模式的文件。但是,如果我的模式类似于subdir/t*.txtmy code for path, subdirs, files in os.walk(root): for fn in fnmatch.filter(files, pattern): print 'found match' 永远不会到达打印语句。据我所见,它永远找不到匹配项,因为文件只是基本名称,不包含子目录。有没有一种很好的方法来匹配包含子目录的模式?不过,对于像

我正在尝试使用fnmatch筛选器查找给定模式的文件。但是,如果我的模式类似于
subdir/t*.txt
my code

for path, subdirs, files in os.walk(root):
    for fn in fnmatch.filter(files, pattern):
        print 'found match'
永远不会到达打印语句。据我所见,它永远找不到匹配项,因为文件只是基本名称,不包含子目录。有没有一种很好的方法来匹配包含子目录的模式?不过,对于像
*.txt
这样的模式,它应该仍然有效


我能想到的唯一解决方案是笨重的,有许多
if
语句和额外的
for
循环(即,检查模式是否是路径,然后从子目录创建所有可能的路径,然后用
fnmatch
检查)。想知道是否有一个优雅的解决方案。提前谢谢

如果在模式中包含前导通配符,则可以将每个文件的完整路径与包含子目录时的路径进行比较,如图所示。因为这样做需要更多的处理,所以可能需要检查是否有必要,如图所示

root = ...
pattern = '*/subdir/subdir2/t*.txt'  # note leading wildcard character

if not os.path.dirname(pattern):  # no subdirectories in pattern
    # no need to compare full paths
    for path, subdirs, files in os.walk(root):
        for fn in fnmatch.filter(files, pattern):
            print('found match - path: "{}", fn: "{}"'.format(path, fn))
else:
    for path, subdirs, files in os.walk(root):
        # must compare full file paths to pattern when it contains directories
        filepaths = (os.path.join(path, file) for file in files)  # generator
        for fp in fnmatch.filter(filepaths, pattern):
            fn = os.path.basename(fp)
            print('match found - path: "{}", fn: "{}"'.format(path, fn))

我意识到martineau的答案仍然不是我所需要的,因为当我有一个像
subdir/pattern
这样的模式时,它非常有效,当我有一个像
subdir/subdir2/pattern
这样的模式时,它不太有效,因为
subdir=os.path.split(path)[1]
将获得单独的subdir(在本例中为
subdir2
),但
subdir\u pat
subdir/subdir2
,因此它不会找到任何匹配项

我最后做的就是改变这一行

subdir = os.path.split(path)[1]  # isolate subdirectory name
对下列事项:

subdir = os.path.replace(root, '')  # I'm not too sure what is a better way to replace paths..
因为我认为当我检查子目录时,它将位于根目录下


任何进一步的反馈都将不胜感激。

感谢您的回答--我使用了它,并为我所需的内容想出了一些解决方案。如果您提供了前导通配符,则修改后的版本将适用于多个子目录在
模式中匹配一个前导目录路径,例如
*/subdir/subdir2/t*.txt
。添加这样的“答案”并不是询问后续问题的正确方法。在这种情况下,您可能应该发布一个新问题。