在 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.paths
assets文件夹中的子文件夹和文件【参考方案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)中递归列出目录和子目录的文件