遍历一个目录中的每个文件

And*_*rew 268 ruby filesystems directory

如何在ruby中编写循环以便我可以在每个文件上执行一段代码?

我是ruby的新手,我已经得出结论,这样做的方法是做每个循环.
ruby文件将从与我想要遍历的目录不同的目录执行.

我试过了Dir.foreach,我无法让它发挥作用.

Tel*_*hus 421

正如其他人所说,这Dir::foreach是一个很好的选择.但是,请注意Dir::foreachDir::entries始终显示...(当前和父目录).你通常不想处理它们,所以你可以这样做:

Dir.foreach('/path/to/dir') do |filename|
  next if filename == '.' or filename == '..'
  # Do work on the remaining files & directories
end
Run Code Online (Sandbox Code Playgroud)

Dir::each_childDir::children显示目录中的所有项目 - 隐藏和非隐藏.通常这是你想要的,但如果不是,你需要做一些事情来跳过隐藏的文件和目录.

或者,您可能希望查看Dir::foreach哪个提供简单的通配符匹配:

Dir.glob('/path/to/dir/*.rb') do |rb_filename|
  # Do work on files & directories ending in .rb
end
Run Code Online (Sandbox Code Playgroud)

  • 如果目录包含大量文件,请使用`Dir.foreach`! (12认同)
  • @mkataja`Dir.foreach`迭代而不是在前面构建一个(可能是巨大的)阵列("Dir.glob"这样做).因此,如果目录非常庞大,它可以产生性能差异.在正常情况下你不会注意到,但在压力条件下,它绝对重要. (10认同)
  • 谢谢!小mod让它变得更好:`如果File.directory那么下一个?item` (5认同)
  • @Tilo:刚出于兴趣,关心更详细一点解释原因?:) (3认同)

Sim*_*lGy 96

这是我最喜欢的易读方法:

Dir.glob("*/*.txt") do |my_text_file|
  puts "working on: #{my_text_file}..."
end
Run Code Online (Sandbox Code Playgroud)

你甚至可以扩展它来处理子目录中的所有文件:

Dir.glob("**/*.txt") do |my_text_file| # note one extra "*"
  puts "working on: #{my_text_file}..."
end
Run Code Online (Sandbox Code Playgroud)


waw*_*wka 29

Dir还有更短的语法来从目录中获取所有文件的数组:

Dir['dir/to/files/*'].each do |fname|
    # do something with fname
end
Run Code Online (Sandbox Code Playgroud)


Fre*_*red 25

Dir.foreach("/home/mydir") do |fname|
  puts fname
end
Run Code Online (Sandbox Code Playgroud)

  • 或者使用Dir#[]或Dir#glob (2认同)

Fai*_*sal 13

查找库专门用于此任务:https: //ruby-doc.org/stdlib-2.5.1/libdoc/find/rdoc/Find.html

require 'find'
Find.find(path) do |file|
  # process
end
Run Code Online (Sandbox Code Playgroud)

这是一个标准的ruby库,因此它应该可用


ska*_*dal 7

我喜欢这个,上面没有提到过.

require 'pathname'

Pathname.new('/my/dir').children.each do |path|
    puts path
end
Run Code Online (Sandbox Code Playgroud)

好处是你得到一个Pathname对象而不是一个字符串,你可以用它来做更多有用的东西并进一步遍历.


ma1*_*w28 7

要跳过.& ..,您可以使用Dir::each_child.

Dir.each_child('/path/to/dir') do |filename|
  puts filename
end
Run Code Online (Sandbox Code Playgroud)

Dir::children 返回一个文件名数组。