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

Posted

技术标签:

【中文标题】遍历一个目录中的每个文件【英文标题】:Iterate through every file in one directory 【发布时间】:2011-01-31 12:28:23 【问题描述】:

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

我是 ruby​​ 新手,我得出的结论是这样做的方法是每个循环。 ruby 文件将从与我要循环的目录不同的目录中执行。

我尝试了Dir.foreach,但无法正常工作。

【问题讨论】:

你能具体说明当你试图让它工作时发生了什么吗?您尝试了哪些确切的代码(或相关的块,如果它很长)?您收到了哪些错误消息? Dir.foreach 用于迭代目录的内容,所以还有很多事情要做。 如果您只想要目录中的文件,请不要忘记在遍历目录内容时测试文件:do_something_with(entry) if File.file?(entry) 使用'img/*.jpg,png,gif,jpeg' 抓取多个扩展。 不幸的是,@ChrisPeters 似乎不太可能,因为 OP 已经四年多没有出现在该网站上了。 【参考方案1】:

正如其他人所说,Dir::foreach 是一个不错的选择。但是,请注意Dir::foreachDir::entries 将始终包括...(当前目录和父目录)。您通常不想处理它们,因此您可以使用Dir::each_childDir::children(如suggested by ma11hew28)或执行以下操作:

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

Dir::foreachDir::entries(以及 Dir::each_childDir::children)还包括隐藏文件和目录。通常这是您想要的,但如果不是,您需要做一些事情来跳过它们。

或者,您可能想查看Dir::glob,它提供了简单的通配符匹配:

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

【讨论】:

如果目录包含大量文件,请使用Dir.foreach 谢谢!让它变得更好的小模组:next if File.directory? item @mr.buttons 这并不总是正确的。有时人们希望处理目录 以及文件。我给出了避免 ... 的特殊列表的代码,因为人们几乎总是想忽略这两个。 @Tilo:只是出于兴趣,想详细解释一下为什么? :) @mkataja Dir.foreach 迭代而不是在前面建立一个(可能很大的)数组(Dir.glob 确实如此)。因此,如果目录真的很大,它会产生性能差异。在正常情况下您不会注意到,但在压力条件下,这绝对很重要。【参考方案2】:

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

Dir.each_child('/path/to/dir') do |filename|
  puts filename
end

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

【讨论】:

【参考方案3】:

find 库是专门为这个任务设计的: https://ruby-doc.org/stdlib-2.5.1/libdoc/find/rdoc/Find.html

require 'find'
Find.find(path) do |file|
  # process
end

这是一个标准的 ruby​​ 库,所以它应该是可用的

【讨论】:

File.find 尽可能递归地向下,从你给它的任何路径开始。我不确定这是 OP 想要的。 我似乎无法使用该方法 - Find.find ?我是否需要下载包含此功能的库? @user470184:“Find”是一个标准的 ruby​​ 库,应该在默认的 ruby​​ 安装中可用。但是,您需要“要求 'find'”才能使用它。 @Faisal 我可以将像*.rb 这样的全局模式传递给find()【参考方案4】:

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

require 'pathname'

Pathname.new('/my/dir').children.each do |path|
    puts path
end

好处是你得到一个路径名对象而不是一个字符串,你可以用它做有用的东西并进一步遍历。

【讨论】:

【参考方案5】:

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

Dir['dir/to/files/*'].each do |fname|
    # do something with fname
end

【讨论】:

这段代码中的什么阻止了目录也被fname的迭代使用?【参考方案6】:

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

Dir.glob("*/*.txt") do |my_text_file|
  puts "working on: #my_text_file..."
end

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

Dir.glob("**/*.txt") do |my_text_file| # note one extra "*"
  puts "working on: #my_text_file..."
end

【讨论】:

【参考方案7】:
Dir.new('/my/dir').each do |name|
  ...
end

【讨论】:

除了 Dir.new('/my/dir') 还有 Dir.entries('/my/dir') 但 Dir.foreach() 更简洁一些。 @Z.E.D.同样Dir.foreach 迭代,而Dir.entries 一次构建整个数组。因此,如果目录很大,则内存不足。 (通常没什么大不了的,可能,但仍然......)【参考方案8】:
Dir.foreach("/home/mydir") do |fname|
  puts fname
end

【讨论】:

或者使用 Dir#[] 或 Dir#glob

以上是关于遍历一个目录中的每个文件的主要内容,如果未能解决你的问题,请参考以下文章

遍历目录中的所有文件并从每个文件中获取平均值

循环遍历给定目录中的文件[重复]

如何使用 Gatling 遍历目录中的所有文件?

R:循环遍历目录中的所有文件,应用列替换命令

需要搜索目录并遍历 zip 文件并阅读每个 [重复]

C语言遍历目录中的文件