我想使用Ruby从一个文件夹中获得所有文件名。
当前回答
如果您想获得包含符号链接的文件名数组,请使用
Dir.new('/path/to/dir').entries.reject { |f| File.directory? f }
甚至
Dir.new('/path/to/dir').reject { |f| File.directory? f }
如果你不想使用符号链接,请使用
Dir.new('/path/to/dir').select { |f| File.file? f }
如其他答案所示,如果你想递归地获得所有文件,使用dir .glob('/path/to/dir/**/*')而不是dir .new('/path/to/dir')。
其他回答
在获取目录中的所有文件名时,此代码段可用于拒绝两个目录[。, . .]和以a开头的隐藏文件。
files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')}
除了这篇文章中的建议,我想提到的是,如果你也需要返回点文件(。gitignore等),与Dir。Glob你需要包括一个标志,如下所示: Dir。一团(“/道路/ / dir / *”,文件::FNM_DOTMATCH) 默认为Dir。条目包括点文件,以及当前的父目录。
对于感兴趣的人,我很好奇这里的答案在执行时间上是如何比较的,下面是针对深度嵌套层次结构的结果。前三个结果是非递归的:
user system total real
Dir[*]: (34900 files stepped over 100 iterations)
0.110729 0.139060 0.249789 ( 0.249961)
Dir.glob(*): (34900 files stepped over 100 iterations)
0.112104 0.142498 0.254602 ( 0.254902)
Dir.entries(): (35600 files stepped over 100 iterations)
0.142441 0.149306 0.291747 ( 0.291998)
Dir[**/*]: (2211600 files stepped over 100 iterations)
9.399860 15.802976 25.202836 ( 25.250166)
Dir.glob(**/*): (2211600 files stepped over 100 iterations)
9.335318 15.657782 24.993100 ( 25.006243)
Dir.entries() recursive walk: (2705500 files stepped over 100 iterations)
14.653018 18.602017 33.255035 ( 33.268056)
Dir.glob(**/*, File::FNM_DOTMATCH): (2705500 files stepped over 100 iterations)
12.178823 19.577409 31.756232 ( 31.767093)
它们是由以下基准测试脚本生成的:
require 'benchmark'
base_dir = "/path/to/dir/"
n = 100
Benchmark.bm do |x|
x.report("Dir[*]:") do
i = 0
n.times do
i = i + Dir["#{base_dir}*"].select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(*):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}/*").select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.entries():") do
i = 0
n.times do
i = i + Dir.entries(base_dir).select {|f| !File.directory? File.join(base_dir, f)}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir[**/*]:") do
i = 0
n.times do
i = i + Dir["#{base_dir}**/*"].select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(**/*):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}**/*").select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.entries() recursive walk:") do
i = 0
n.times do
def walk_dir(dir, result)
Dir.entries(dir).each do |file|
next if file == ".." || file == "."
path = File.join(dir, file)
if Dir.exist?(path)
walk_dir(path, result)
else
result << file
end
end
end
result = Array.new
walk_dir(base_dir, result)
i = i + result.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(**/*, File::FNM_DOTMATCH):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}**/*", File::FNM_DOTMATCH).select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
end
文件计数的差异是由于Dir。默认情况下包含隐藏文件的条目。Dir。在这种情况下,由于需要重新构建文件的绝对路径以确定文件是否为目录,条目最终花费的时间要长一些,但即使没有这一点,在递归情况下,它仍然比其他选项花费的时间要长。这都是在OSX上使用ruby 2.5.1完成的。
如果你用空格创建目录:
mkdir "a b"
touch "a b/c"
你不需要转义目录名,它会自动完成:
p Dir["a b/*"] # => ["a b/c"]
Dir.entries(folder)
例子:
Dir.entries(".")
来源:http://ruby-doc.org/core/classes/Dir.html method-c-entries
这对我来说很管用:
如果你不想要隐藏文件[1],使用Dir[]:
# With a relative path, Dir[] will return relative paths
# as `[ './myfile', ... ]`
#
Dir[ './*' ].select{ |f| File.file? f }
# Want just the filename?
# as: [ 'myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.basename f }
# Turn them into absolute paths?
# [ '/path/to/myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.absolute_path f }
# With an absolute path, Dir[] will return absolute paths:
# as: [ '/home/../home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }
# Need the paths to be canonical?
# as: [ '/home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }.map{ |f| File.expand_path f }
现在,Dir。条目将返回隐藏的文件,并且您不需要通配符asterix(您可以直接将目录名传递给变量),但它将直接返回basename,因此File. xml将返回文件。XXX函数不能工作。
# In the current working dir:
#
Dir.entries( '.' ).select{ |f| File.file? f }
# In another directory, relative or otherwise, you need to transform the path
# so it is either absolute, or relative to the current working dir to call File.xxx functions:
#
home = "/home/test"
Dir.entries( home ).select{ |f| File.file? File.join( home, f ) }
[1] .dotfile在unix上,我不知道Windows上
推荐文章
- RVM不是一个函数,用' RVM use…’不会起作用
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 了解Gemfile。锁文件
- 如何确定一个数组是否包含另一个数组的所有元素
- 是什么导致这个ActiveRecord::ReadOnlyRecord错误?
- 最好的打印散列的方法
- 如何删除文件中的特定行?
- Rails:dependent =>:destroy VS:dependent =>:delete_all
- 我可以在不包含Ruby模块的情况下调用实例方法吗?
- 如何将新项目添加到哈希
- 测试一个Ruby类是否是另一个类的子类
- 什么时候使用Struct vs. OpenStruct?
- 数组到哈希Ruby
- 使用Java重命名文件
- 我如何让红宝石打印一个完整的回溯而不是截断一个?