在 Ruby 中递归列出目录的单线器?

Posted

技术标签:

【中文标题】在 Ruby 中递归列出目录的单线器?【英文标题】:One-liner to recursively list directories in Ruby? 【发布时间】:2011-01-23 03:56:28 【问题描述】:

在 Ruby 中获取目录数组(不包括文件)的最快、最优化、单行方式是什么?

包含文件怎么样?

【问题讨论】:

最快、最优化和单行可能与可读/可维护不一致。而且,您可以使用基准测试和快速测试来发现这一点。 【参考方案1】:
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files

你也可以写Dir[foo]而不是Dir.glob(foo)(但是Dir.glob也可以接受一个块,在这种情况下它将产生每个路径而不是创建一个数组)。

Ruby Glob Docs

【讨论】:

使用Dir.glob("**/"),除非你也想要符号链接 隐藏文件和目录呢? 要在匹配结果中包含点文件,请使用File::FNM_DOTMATCH 标志。 谢谢@x-yuri!顺便说一句,标志是这样指定的:Dir.glob("**/*", File::FNM_DOTMATCH) 这是文档:ruby-doc.org/core-2.2.0/Dir.html#method-c-glob【参考方案2】:

这是一个将 Rails 项目目录的动态发现与 Dir.glob 结合起来的示例:

dir = Dir.glob(Rails.root.join('app', 'assets', 'stylesheets', '*'))

【讨论】:

我试过了>>config.assets.paths << Rails.root.join("app", "assets", "*"),但仍然看不到Rails.application.config.assets.pathsassets文件夹中的子文件夹和文件【参考方案3】:

正如此处其他答案所述,您可以使用Dir.glob。请记住,文件夹中可能包含许多奇怪的字符,并且 glob 参数是模式,因此某些字符具有特殊含义。因此,执行以下操作是不安全的:

Dir.glob("#folder/**/*")

改为:

Dir.chdir(folder)  Dir.glob("**/*").map |path| File.expand_path(path)  

【讨论】:

【参考方案4】:

我相信这里的解决方案都没有处理隐藏目录(例如'.test'):

require 'find'
Find.find('.')  |e| puts e if File.directory?(e) 

【讨论】:

Find.find('/tmp').collect |_|_ 对我有帮助 小心查找,它不遵循符号链接:***.com/questions/3974087/…【参考方案5】:
Dir.open(Dir.pwd).map  |h| (File.file?(h) ? "#h - file" : "#h - folder") if h[0] != '.' 

dots 返回 nil,使用 compact

【讨论】:

这不太优雅,需要多写几行才能如此【参考方案6】:

php 或其他语言中,要获取目录及其所有子目录的内容,您必须编写几行代码,但在 Ruby 中则需要 2 行:

require 'find'
Find.find('./') do |f| p f end

这将打印当前目录及其所有子目录的内容。

或者更短,您可以使用’**’ 表示法:

p Dir['**/*.*']

你会用 PHP 或 Java 写多少行来获得相同的结果?

【讨论】:

拒绝直接从mustap.com/rubyzone_post_162_recursive-directory-listing 复制粘贴而不引用来源... @kivetros 我编辑了答案以包含链接的存档版本:-)【参考方案7】:

虽然不是单行解决方案,但我认为这是使用 ruby​​ 调用的最佳方法。

先递归删除所有文件 第二次删除所有空目录

Dir.glob("./logs/**/*").each  |file| File.delete(file) if File.file? file 
Dir.glob("./logs/**/*/").each  |directory| Dir.delete(directory) 

【讨论】:

他/她不想删除文件/目录。 如何在一行中对两个文件+目录执行此操作? 哇,这是一个非常糟糕的答案:a.)它没有回答最初的问题,b.)当一个没有经验的人 c&p 时它是破坏性的......【参考方案8】:

目录列表试试

Dir['**/']

文件列表比较难,因为在 Unix 中目录也是一个文件,所以你需要测试类型或从返回的列表中删除条目,该列表是其他条目的父项。

Dir['**/*'].reject |fn| File.directory?(fn) 

对于所有文件和目录的简单列表

Dir['**/*']

【讨论】:

请注意,他说的是“还包含文件”,而不是“仅包含文件”,因此您无需删除目录。 @sepp2k 是的,我在玩 irb 时错过了这部分。但是我把它留在这里以防有人可能会搜索类似的东西:-)【参考方案9】:

快速一班

仅目录

`find -type d`.split("\n")

目录和普通文件

`find -type d -or -type f`.split("\n")`

纯净美丽的红宝石

require "pathname"

def rec_path(path, file= false)
  puts path
  path.children.collect do |child|
    if file and child.file?
      child
    elsif child.directory?
      rec_path(child, file) + [child]
    end
  end.select  |x| x .flatten(1)
end

# only directories
rec_path(Pathname.new(dir), false)
# directories and normal files
rec_path(Pathname.new(dir), true)

【讨论】:

错误:Dir.glob("#DIRECTORY/**/*/").map |directory|路径名.new(目录) 谁能解释一下end.select .flatten() 部分?我喜欢这个功能。看起来这将创建一个数组数组?是否可以使用 rec_path(child, file) << child.to_s 来执行 elseif 部分,以便您可以将其分配给一个数组并获取一个字符串数组?谢谢!

以上是关于在 Ruby 中递归列出目录的单线器?的主要内容,如果未能解决你的问题,请参考以下文章

在 Ruby 中,如何在目录列表中的文件夹之前列出/排序文件?

在Databricks(DBFS)中递归列出目录和子目录的文件

PHP - 在下拉菜单中递归列出所有目录和子目录[重复]

如何在shell的递归目录中列出特定类型的文件?

在 zipfile 中递归列出所有目录而不在 python 中提取

递归法列出目录中的所有文件