【问题标题】:Getting a list of folders in a directory获取目录中的文件夹列表
【发布时间】:2010-12-26 07:47:55
【问题描述】:

如何使用 ruby​​ 获取某个目录中存在的文件夹列表?

Dir.entries() 看起来很接近,但我不知道如何仅限于文件夹。

【问题讨论】:

    标签: ruby directory directory-listing


    【解决方案1】:

    我认为您可以测试每个文件以查看它是否是带有FileTest.directory? (file_name) 的目录。请参阅the documentation for FileTest 了解更多信息。

    【讨论】:

      【解决方案2】:

      您可以使用FileTest 模块中的File.directory? 来确定文件是否为目录。将其与Dir.entries 结合起来,就可以得到一个不错的单(ish)-liner:

      directory = 'some_dir'
      Dir.entries(directory).select { |file| File.directory?(File.join(directory, file)) }
      

      编辑:根据 ScottD 的更正更新。

      【讨论】:

        【解决方案3】:

        Jordan 已接近,但 Dir.entries 没有返回 File.directory? 期望的完整路径。试试这个:

         Dir.entries('/your_dir').select {|entry| File.directory? File.join('/your_dir',entry) and !(entry =='.' || entry == '..') }
        

        【讨论】:

        • 请注意,这将为您提供所有目录,包括隐藏目录以及'.'(当前目录)和'..'(当前目录的父目录)。在大多数情况下,您至少要删除这两个。
        • 我更喜欢这个...Dir.entries(root).select { |entry| File.directory? File.join(root, entry) and not entry.in? %w[. ..]}
        • 但我使用Dir.glob 提出了一个更加清晰简洁的解决方案。
        • 这只是客观上比 Dir.glob() 在其他答案中看到的更糟糕——我强烈建议这样做而不是这样做
        【解决方案4】:
        directory = 'Folder'
        puts Dir.entries(directory).select { |file| File.directory? File.join(directory, file)}
        

        【讨论】:

          【解决方案5】:

          在我看来,Pathname 比普通字符串更适合文件名。

          require "pathname"
          Pathname.new(directory_name).children.select { |c| c.directory? }
          

          这为您提供了该目录中所有目录的数组作为路径名对象。

          如果你想要字符串

          Pathname.new(directory_name).children.select { |c| c.directory? }.collect { |p| p.to_s }
          

          如果directory_name 是绝对的,那么这些字符串也是绝对的。

          【讨论】:

          • 使用Pathname的另一个原因是它会自动删除...和像.DS_Store这样的专有文件
          • 更简洁:Pathname.new(somepath).children.select(&:directory?)
          【解决方案6】:

          我发现这更有用且易于使用:

          Dir.chdir('/destination_directory')
          Dir.glob('*').select {|f| File.directory? f}
          

          它获取当前目录中的所有文件夹,不包括...

          要递归文件夹,只需使用 ** 代替 *

          Dir.glob 行也可以作为一个块传递给Dir.chdir

          Dir.chdir('/destination directory') do
            Dir.glob('*').select { |f| File.directory? f }
          end
          

          【讨论】:

          • 要递归文件夹,您需要使用**/* 代替*
          • 简单而最好。谢谢
          • 优秀的答案。
          【解决方案7】:

          递归查找某个目录下的所有文件夹:

          Dir.glob 'certain_directory/**/*/'
          

          非递归版本:

          Dir.glob 'certain_directory/*/'
          

          注意:Dir.[] 的作用类似于 Dir.glob

          【讨论】:

          • 如何使用相同的逻辑进行递归和非递归文件查找?以及如何递归和非递归文件和文件夹?
          【解决方案8】:
          Dir.glob('/your_dir').reject {|e| !File.directory?(e)}
          

          【讨论】:

          • 或者,代替reject !select
          【解决方案9】:
          $dir_target = "/Users/david/Movies/Camtasia 2/AzureMobileServices.cmproj/media"
          
          Dir.glob("#{$dir_target}/**/*").each do |f| 
            if File.directory?(f)
              puts "#{f}\n"
            end
          end
          

          【讨论】:

            【解决方案10】:

            对于您可能想要使用的通用解决方案

            Dir.glob(File.expand_path(path))
            

            这将适用于~/*/(您的主目录中的所有文件夹)之类的路径。

            【讨论】:

            • 谢谢!这很有帮助。
            【解决方案11】:

            我们可以结合Borh's answerjohannes' answer 来获得一个非常优雅的解决方案来获取文件夹中的目录名称。

            # user globbing to get a list of directories for a path
            base_dir_path = ''
            directory_paths = Dir.glob(File.join(base_dir_path, '*', ''))
            
            # or recursive version:
            directory_paths = Dir.glob(File.join(base_dir_path, '**', '*', ''))
            
            # cast to Pathname
            directories = directory_paths.collect {|path| Pathname.new(path) }
            
            # return the basename of the directories
            directory_names = directories.collect {|dir| dir.basename.to_s }
            

            【讨论】:

              【解决方案12】:

              仅文件夹(不包括“.”和“..”):

              Dir.glob(File.join(path, "*", File::SEPARATOR))

              文件夹和文件:

              Dir.glob(File.join(path, "*"))

              【讨论】:

                【解决方案13】:

                有了这个,您可以获得目录子目录子子目录完整路径数组> 以递归方式。 我使用该代码将这些文件加载​​到 config/application 文件中。

                Dir.glob("path/to/your/dir/**/*").select { |entry| File.directory? entry }
                

                此外,我们不再需要处理无聊的...。接受的答案需要处理它们。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-06-23
                  • 1970-01-01
                  • 2015-11-30
                  相关资源
                  最近更新 更多