一线在Ruby中递归列出目录?


96

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

如何包含文件?


2
最快,最优化和单线可能与可读/可维护的不一致。而且,您可以使用基准测试和快速测试来找出答案。
锡人

Answers:


180
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files

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

Ruby Glob文件


10
Dir.glob("**/")除非您也想要符号链接,否则请使用
约翰内斯(Johannes)2010年

6
隐藏的文件和目录呢?
alediaferia 2012年

6
要将点文件包括在匹配结果中,请使用File::FNM_DOTMATCH标志。
x-yuri 2014年

2
谢谢@ x-yuri!标志btw的指定如下:Dir.glob("**/*", File::FNM_DOTMATCH)
vlz 2014年



31

有关目录列表,请尝试

Dir['**/']

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

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

并且仅列出所有文件和目录

Dir['**/*']

请注意,他说的是“还包括文件”,而不是“仅文件”,因此您不需要删除目录。
sepp2k 2010年

1
@ sepp2k是的,我在玩irb时错过了这一部分。但是我将其保留在这里,以防有人可能搜索类似的内容:-)
MBO,2010年

7

快一班轮

仅目录

`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)

1
False:Dir.glob(“#{DIRECTORY} / ** / * /”)。map {| directory | Pathname.new(directory)}
罗伯特·罗斯

谁能解释这个end.select {}.flatten()部分?我总体上喜欢这个功能。看起来会创建一个数组数组?可以用以下方式完成该elseif部分:rec_path(child, file) << child.to_s以便将其分配给一个数组并获得一个字符串数组吗?谢谢!
MCP 2013年

7

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

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

而是:

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

2

在PHP或其他语言中,要获取目录及其所有子目录的内容,必须编写一些代码行,但是在Ruby中,它需要两行代码:

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

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

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

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

您将用PHP或Java写几行以获得相同的结果?


13
不推荐使用直接从mustap.com/rubyzone_post_162_recursive-directory-listing复制粘贴而无需引用源...
eckza 2011年

@kivetros我编辑了答案,以包括链接的存档版本:-)
onebree

0

尽管不是单一解决方案,但我认为这是使用ruby调用的最佳方法。

首先以递归方式删除所有文件,
其次删除所有空目录

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

3
他/她不想删除文件/目录。
DarekNędza2015年

如何在一行中同时对文件和目录执行此操作?
vipin8169 '16

0

这是一个结合了动态发现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
vipin8169'3

-1
Dir.open(Dir.pwd).map { |h| (File.file?(h) ? "#{h} - file" : "#{h} - folder") if h[0] != '.' }

点返回零,使用紧凑


1
这不是太优雅,需要在其他几行上
才是
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.