Каков самый быстрый, наиболее оптимизированный и однострочный способ получить массив каталогов (исключая файлы) в Ruby?
Как насчет включения файлов?
Каков самый быстрый, наиболее оптимизированный и однострочный способ получить массив каталогов (исключая файлы) в Ruby?
Как насчет включения файлов?
Ответы:
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files
Вместо этого Dir.glob(foo)
вы также можете написать Dir[foo]
(но Dir.glob
также можете взять блок, и в этом случае он будет выдавать каждый путь вместо создания массива).
Dir.glob("**/")
если вам также не нужны символические ссылки
File::FNM_DOTMATCH
флаг.
Dir.glob("**/*", File::FNM_DOTMATCH)
Я считаю, что ни одно из решений здесь не касается скрытых каталогов (например, '.test'):
require 'find'
Find.find('.') { |e| puts e if File.directory?(e) }
Find.find('/tmp').collect {|_|_}
Был полезен для меня
Для списка каталогов попробуйте
Dir['**/']
Список файлов сложнее, потому что в каталоге Unix также есть файл, поэтому вам нужно проверить тип или удалить записи из возвращенного списка, который является родительским для других записей.
Dir['**/*'].reject {|fn| File.directory?(fn) }
А для получения списка всех файлов и каталогов просто
Dir['**/*']
Только каталоги
`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)
end.select {}.flatten()
часть? Мне нравится эта функция в целом. Похоже, что создадим массив массивов? Можно ли выполнить эту elseif
часть с помощью:, rec_path(child, file) << child.to_s
чтобы вы могли назначить ее массиву и получить массив строк? Спасибо!
Как отмечено в других ответах здесь, вы можете использовать Dir.glob
. Имейте в виду, что в папках может быть много странных символов, а аргументы glob являются шаблонами, поэтому некоторые символы имеют особое значение. Поэтому небезопасно делать что-то вроде следующего:
Dir.glob("#{folder}/**/*")
Вместо этого сделайте:
Dir.chdir(folder) { Dir.glob("**/*").map {|path| File.expand_path(path) } }
В PHP или других языках, чтобы получить содержимое каталога и всех его подкаталогов, вам нужно написать несколько строк кода, но в Ruby это занимает 2 строки:
require 'find'
Find.find('./') do |f| p f end
это напечатает содержимое текущего каталога и всех его подкаталогов.
Или, короче, можно использовать ’**’
обозначение:
p Dir['**/*.*']
Сколько строк вы напишете на PHP или на Java, чтобы получить тот же результат?
Хотя это и не однострочное решение, я думаю, что это лучший способ сделать это с помощью вызовов ruby.
Сначала удалите все файлы рекурсивно.
Затем удалите все пустые каталоги.
Dir.glob("./logs/**/*").each { |file| File.delete(file) if File.file? file }
Dir.glob("./logs/**/*/").each { |directory| Dir.delete(directory) }
Вот пример, сочетающий динамическое обнаружение каталога проекта Rails с Dir.glob:
dir = Dir.glob(Rails.root.join('app', 'assets', 'stylesheets', '*'))
config.assets.paths << Rails.root.join("app", "assets", "*")
, но все еще не мог видеть подпапки и файлы внутри папки с ресурсами, авторRails.application.config.assets.paths