Итерации через каждый файл в одном каталоге

Как написать цикл в 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 возвращает массив имен файлов.