【问题标题】:Python fnmatch filter for patterns that include subdirectory用于包含子目录的模式的 Python fnmatch 过滤器
【发布时间】:2016-01-05 04:32:15
【问题描述】:

我正在尝试使用 fnmatch 过滤器来查找给定模式的文件。但是,如果我的模式类似于 subdir/t*.txt 我的代码

for path, subdirs, files in os.walk(root):
    for fn in fnmatch.filter(files, pattern):
        print 'found match'

永远不会到达 print 语句。据我所知,它永远不会找到匹配项,因为 files 只是基本名称,并且不会包含子目录。有没有一种匹配包含子目录的模式的好方法?不过,它应该仍然适用于 *.txt 这样的模式。

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

【问题讨论】:

    标签: python path


    【解决方案1】:

    如果您在显示的模式中包含前导通配符,则可以通过使fnmatch.filter() 将每个文件的完整路径与其包含子目录的时间进行比较。由于这样做需要更多的处理,因此可能值得检查是否有必要,如图所示。

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

    【讨论】:

    • 感谢您的回答——我使用它并想出了一些我需要的东西。
    • 如果您在pattern 中提供前导通配符以匹配前导目录路径(例如*/subdir/subdir2/t*.txt),则修改后的版本将与多个子目录一起使用。
    【解决方案2】:

    我意识到 martineau 的答案仍然不是我所需要的,因为虽然当我有像 subdir/pattern 这样的模式时它工作得很好,但当我有像 subdir/subdir2/pattern 这样的模式时,它并不完全工作,因为 subdir = os.path.split(path)[1] 会得到单个子目录(在本例中为 subdir2),但 subdir_patsubdir/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..
    

    因为我发现当我检查子目录时,它会在根目录下。

    感谢任何进一步的反馈。

    【讨论】:

    • 添加这样的“答案”确实不是提出后续问题的正确方法。在这种情况下,您可能应该发布一个新问题。
    猜你喜欢
    • 2011-03-28
    • 2014-05-30
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多