【问题标题】:Python Glob.glob: a wildcard for the number of directories between the root and the destinationPython Glob.glob:根和目标之间的目录数量的通配符
【发布时间】:2012-07-12 14:43:47
【问题描述】:

好的,我不仅在问题本身上遇到了麻烦,甚至在试图解释我的问题时也遇到了麻烦。我有一个由大约 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,并允许我遍历它们。非常感谢!

【问题讨论】:

    标签: python path wildcard glob


    【解决方案1】:

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

    【讨论】:

    • 但请注意,'**' glob 模式不遵循符号链接,因为它可能会陷入无限循环。
    【解决方案2】:

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

    import formic
    fileset = formic.FileSet(include="rootdir/**/destinationdir/*")
    
    for file_name in fileset:
        # Do something with file_name
    

    【讨论】:

      【解决方案3】:

      我认为使用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)
      

      【讨论】:

        【解决方案4】:

        这看起来更容易使用更通用的工具来完成,比如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 并自己拆分参数。不过,如图所示,它是安全的。

        【讨论】:

          【解决方案5】:

          您可以为每个缩进级别创建一个模式(如果需要,增加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”目录所在的位置,第二个阶段是执行操作。

          【讨论】:

          • 我最喜欢这个答案,因为您实际上使用 glob,而且它很简单。
          猜你喜欢
          • 1970-01-01
          • 2010-12-28
          • 1970-01-01
          • 1970-01-01
          • 2020-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-05
          相关资源
          最近更新 更多