6

好的,我不仅在问题本身上遇到了麻烦,甚至在试图解释我的问题时也遇到了麻烦。我有一个由大约 7 次迭代组成的目录树,所以:rootdir/a/b/c/d/e/f/destinationdir

问题是有些可能有 5 个子目录级别,有些可能有多达 10 个,例如:

rootdir/a/b/c/d/destinationdir

或者:

rootdir/a/b/c/d/e/f/g/h/destinationdir

他们唯一的共同点是目标目录总是被命名为相同的东西。我使用 glob 函数的方式如下:

for path in glob.glob('/rootdir/*/*/*/*/*/*/destinationdir'):
--- os.system('cd {0}; do whatever'.format(path))

但是,这仅适用于具有精确数量的中间子目录的目录。有什么办法让我不必指定那个数量subdirectories(asterices); 换句话说,无论中间子目录的数量是多少,让函数到达destinationdir,并允许我遍历它们。非常感谢!

4

5 回答 5

5

我认为这可以通过以下方式更轻松地完成os.walk

def find_files(root,filename):
    for directory,subdirs,files in os.walk(root):
        if filename in files:
            yield os.join(root,directory,filename)

当然,这不允许您在文件名部分使用 glob 表达式,但您可以使用 regex 或 fnmatch 来检查这些内容。

编辑

或查找目录:

def find_files(root,d):
    for directory,subdirs,files in os.walk(root):
        if d in subdirs:
            yield os.join(root,directory,d)
于 2012-07-12T19:41:04.787 回答
4

您可以为每个缩进级别创建一个模式(10如果需要增加):

for i in xrange(10):
    pattern = '/rootdir/' + ('*/' * i) + 'destinationdir'
    for path in glob.glob(pattern):
        os.system('cd {0}; do whatever'.format(path))

这将迭代:

'/rootdir/destinationdir'
'/rootdir/*/destinationdir'
'/rootdir/*/*/destinationdir'
'/rootdir/*/*/*/destinationdir'
'/rootdir/*/*/*/*/destinationdir'
'/rootdir/*/*/*/*/*/destinationdir'
'/rootdir/*/*/*/*/*/*/destinationdir'
'/rootdir/*/*/*/*/*/*/*/destinationdir'
'/rootdir/*/*/*/*/*/*/*/*/destinationdir'
'/rootdir/*/*/*/*/*/*/*/*/*/destinationdir'

如果您必须遍历任意深度的目录,那么我建议将算法分为两个步骤:一个阶段是调查所有“destinationdir”目录的位置,第二个阶段是执行操作。

于 2012-07-12T19:06:56.030 回答
2

如果你正在寻找文件,你可以使用Formic 包(披露:我写的)——它使用 '**' 通配符实现了 Apache Ant 的 FileSet Glob:

import formic
fileset = formic.FileSet(include="rootdir/**/destinationdir/*")

for file_name in fileset:
    # Do something with file_name
于 2012-07-13T00:29:09.413 回答
2

Python 3 glob.glob现在接受双通配符来指定任意数量的中间目录

于 2018-08-06T08:24:31.050 回答
1

这看起来更容易使用更通用的工具来完成,比如find命令(你的os.system调用表明你在一个类似 unix 的系统上,所以这会起作用)。

os.system('find /rootdir -mindepth 5 -maxdepth 10 -type d -name destinationdir | while read d; do ( cd $d && do whatever; ); done')

..请注意,如果您要将任何用户提供的字符串放入该命令,这将变得非常不安全,您应该使用 subprocess.Popen 代替,执行 shell 并自己拆分参数。不过,如图所示,它是安全的。

于 2012-07-12T19:34:03.130 回答