Итерации через каждый файл в одном каталоге
Как написать цикл в ruby, чтобы я мог выполнить блок кода для каждого файла?
Я новичок в рубине, и я пришел к выводу, что способ сделать это - делать каждый цикл.
Файл ruby будет выполнен из другого каталога, кроме каталога, в который я хочу выполнить цикл.
Я пробовал Dir.foreach
, и я не мог заставить его работать.
Ответы
Ответ 1
Как уже говорили другие, Dir::foreach
здесь хороший вариант. Однако обратите внимание, что Dir::foreach
и Dir::entries
всегда будут включать в себя .
и ..
(текущий и родительский каталоги). Как правило, вы не хотите над ними работать, поэтому вы можете использовать Dir::each_child
или Dir::children
(как предложено ma11hew28) или сделать что-то подобное :
Dir.foreach('/path/to/dir') do |filename|
next if filename == '.' or filename == '..'
# Do work on the remaining files & directories
end
Dir::foreach
и Dir::entries
(а также Dir::each_child
и Dir::children
) также включают скрытые файлы & каталоги. Часто это то, что вы хотите, но если это не так, вам нужно что-то сделать, чтобы пропустить их.
В качестве альтернативы вы можете обратиться к Dir::glob
, который обеспечивает простое сопоставление с подстановочными знаками:
Dir.glob('/path/to/dir/*.rb') do |rb_filename|
# Do work on files & directories ending in .rb
end
Ответ 2
Это мой любимый метод для легкого чтения:
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
Ответ 3
Dir также имеет более короткий синтаксис для получения массива всех файлов из каталога:
Dir['dir/to/files/*'].each do |fname|
# do something with fname
end
Ответ 4
Dir.foreach("/home/mydir") do |fname|
puts fname
end
Ответ 5
Библиотека find разработана специально для этой задачи:
https://ruby-doc.org/stdlib-2.5.1/libdoc/find/rdoc/Find.html
require 'find'
Find.find(path) do |file|
# process
end
Это стандартная библиотека ruby, поэтому она должна быть доступна
Ответ 6
Мне нравится этот, который не упоминался выше.
require 'pathname'
Pathname.new('/my/dir').children.each do |path|
puts path
end
Преимущество состоит в том, что вы получаете объект Pathname вместо строки, который вы можете делать с полезными вещами и далее.
Ответ 7
Dir.new('/my/dir').each do |name|
...
end
Ответ 8
Пропустить .
& ..
, вы можете использовать Dir::each_child
.
Dir.each_child('/path/to/dir') do |filename|
puts filename
end
Dir::children
возвращает массив имен файлов.