只蚂蚁都有一个很好的方式来选择组的文件,最轻易使用**指示目录树。E.g。

**/CVS/*            # All files immediately under a CVS directory.
mydir/mysubdir/**   # All files recursively under mysubdir

更多的例子可以在这里看到:

http://ant.apache.org/manual/dirtasks.html

你会如何实现这蟒蛇,这样你可以做一些事情,如:

files = get_files("**/CVS/*")
for file in files:
    print file

=>
CVS/Repository
mydir/mysubdir/CVS/Entries
mydir/mysubdir/foo/bar/CVS/Entries
有帮助吗?

解决方案

只要你遇到一个 **, 你们要recurse通过的整体目录的结构,因此,我认为在这一点上,最简单的方法是循环,通过目录的操作系统。走路,建造一条路径,然后检查,如果有匹配的模式。你也许可以转换为一个regex通过这样的:

def glob_to_regex(pat, dirsep=os.sep):
    dirsep = re.escape(dirsep)
    print re.escape(pat)
    regex = (re.escape(pat).replace("\\*\\*"+dirsep,".*")
                           .replace("\\*\\*",".*")
                           .replace("\\*","[^%s]*" % dirsep)
                           .replace("\\?","[^%s]" % dirsep))
    return re.compile(regex+"$")

(虽然注意,这不是齐全的-它不会支持 [a-z] 风格glob模式为实例,虽然这可能是后加的)。(第一 \*\*/ 比赛是要涵盖这样的情况 \*\*/CVS 匹配 ./CVS, 以及具有只是 \*\* 来比赛的尾部。)

然而,很显然你不想recurse通过下面的一切现dir时不处理一个 ** 图案,因此我认为你需要一个两阶段的做法。我没有试图实施以下,并有可能的几个角落的情况,但我认为它应当工作:

  1. 分裂纹在你的目录分离.即 pat.split('/') -> ['**','CVS','*']

  2. Recurse通过目录,并期待在相关模式的一部分用于这个水平。ie。 n levels deep -> look at pat[n].

  3. 如果 pat[n] == '**' 关于上述战略:

    • 重建的图案 dirsep.join(pat[n:])
    • 转换到一个与regex glob\_to\_regex()
    • 递归 os.walk 通过当前的目录,建立起路径相对水平,你开始。如果路相匹配的regex,产率。
  4. 如果帕特不匹配 "**", ,这是最后一个元素中的模式,则产量的所有文件/dirs匹配 glob.glob(os.path.join(curpath,pat[n]))

  5. 如果帕特不匹配 "**", 和不是最后的元素中的模式,然后为每个目录,检查其是否符合(用滴) pat[n].如果是这样,recurse下通过它,增加深度(此它将看看 pat[n+1])

其他提示

对不起,这是你的OP后很长一段时间。我刚刚发布了一个Python包,它正是这样做的 - 它叫做Formic,它可以在 PyPI Cheeseshop 。使用Formic,您的问题可通过以下方式解决:

import formic
fileset = formic.FileSet(include="**/CVS/*", default_excludes=False)
for file_name in fileset.qualified_files():
    print file_name

有一个轻微的复杂性:default_excludes。 Formic,就像Ant一样,默认情况下排除CVS目录(因为大多数情况下从构建文件中收集文件是危险的),问题的默认答案将导致没有文件。设置default_excludes = False会禁用此行为。

os.walk 是你的朋友。查看Python手册中的示例 ( https://docs.python.org/2/library/os .html#os.walk )并尝试从中构建一些东西。

匹配“ ** / CVS / * ”根据您获得的文件名,您可以执行以下操作:

def match(pattern, filename):
    if pattern.startswith("**"):
        return fnmatch.fnmatch(file, pattern[1:])
    else:
        return fnmatch.fnmatch(file, pattern)

fnmatch.fnmatch 中," *"匹配任何东西(包括斜杠)。

'waf'构建系统源代码中有一个实现。 http://code.google的.com / p / WAF /源/浏览/中继/ waflib / Node.py R = 10755#471 可能这应该包含在自己的库中吗?

烨。正如已经建议的那样,你最好的选择是使用'os.walk'。或者,围绕' glob '和' fnmatch '模块,或许。

os.walk 是您最好的选择为了这。我用.svn做了下面的例子,因为我有这个方便,而且效果很好:

import re

for (dirpath, dirnames, filenames) in os.walk("."):
    if re.search(r'\.svn, dirpath):
        for file in filenames:
            print file
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top