it-swarm.dev

Однострочник для рекурсивного перечисления каталогов в Ruby?

Какой самый быстрый, самый оптимизированный, однострочный способ получения массива каталогов (исключая файлы) в Ruby?

Как насчет включения файлов?

92
Lance Pollard
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files

Вместо Dir.glob(foo) вы также можете написать Dir[foo] (однако Dir.glob также может занять блок, и в этом случае он будет выдавать каждый путь вместо создания массива).

Ruby Glob Docs

164
sepp2k

Я полагаю, что ни одно из решений здесь не имеет дело со скрытыми каталогами (например, '.test'):

require 'find'
Find.find('.') { |e| puts e if File.directory?(e) }
53
FelipeC

Для списка каталогов попробуйте

Dir['**/']

Список файлов сложнее, потому что в каталоге Unix также есть файл, поэтому вам нужно проверить тип или удалить записи из возвращенного списка, который является родительским для других записей.

Dir['**/*'].reject {|fn| File.directory?(fn) }

А для списка всех файлов и каталогов просто

Dir['**/*']
27
MBO

Быстро один лайнер

Только каталоги

`find -type d`.split("\n")

Каталоги и нормальные файлы

`find -type d -or -type f`.split("\n")`

Чисто красивый Рубин

require "pathname"

def rec_path(path, file= false)
  puts path
  path.children.collect do |child|
    if file and child.file?
      child
    elsif child.directory?
      rec_path(child, file) + [child]
    end
  end.select { |x| x }.flatten(1)
end

# only directories
rec_path(Pathname.new(dir), false)
# directories and normal files
rec_path(Pathname.new(dir), true)
7
johannes

Как отмечено в других ответах здесь, вы можете использовать Dir.glob. Имейте в виду, что в папках может быть много странных символов, а аргументы glob - это шаблоны, поэтому некоторые символы имеют особое значение. Поэтому небезопасно делать что-то вроде следующего:

Dir.glob("#{folder}/**/*")

Вместо этого сделайте:

Dir.chdir(folder) { Dir.glob("**/*").map {|path| File.expand_path(path) } }
6
troelskn

В PHP или других языках для получения содержимого каталога и всех его подкаталогов вам нужно написать несколько строк кода, но в Ruby требуется 2 строки:

require 'find'
Find.find('./') do |f| p f end

это напечатает содержимое текущего каталога и всех его подкаталогов.

Или короче, вы можете использовать нотацию ’**’:

p Dir['**/*.*']

Сколько строк вы напишите в PHP или в Java, чтобы получить тот же результат?

2
Ramesh

Вот пример, который сочетает динамическое обнаружение каталога проекта Rails с Dir.glob:

dir = Dir.glob(Rails.root.join('app', 'assets', 'stylesheets', '*'))
0
shacker

Хотя это не однострочное решение, я думаю, что это лучший способ сделать это с помощью вызовов Ruby.

Сначала рекурсивно удалите все файлы
Затем удалите все пустые каталоги.

Dir.glob("./logs/**/*").each { |file| File.delete(file) if File.file? file }
Dir.glob("./logs/**/*/").each { |directory| Dir.delete(directory) }
0
HomeTurf