Я пытаюсь найти все файлы определенного типа (например .pdf) в данной папке и скопировать их в новую папку. То, что мне нужно, это указать корневую папку и выполнить поиск по этой папке и всем ее подпапкам для любых файлов, которые соответствуют данному типу (.pdf). Может кто-нибудь дать мне руку на то, как я должен искать вложенные папки корневой папки и их подпапки и так далее. Похоже, что рекурсивный метод мог бы сделать трюк здесь, но я не могу реализовать его правильно? (Я, кстати, реализую эту программу в рубине).
Поиск папки и всех ее подпапок для файлов определенного типа
Ответ 1
Вам нужен модуль Find. Find.find
берет строку, содержащую путь, и передает родительский путь вместе с путем каждого файла и подкаталога в сопроводительный блок. Пример кода:
require 'find'
pdf_file_paths = []
Find.find('path/to/search') do |path|
pdf_file_paths << path if path =~ /.*\.pdf$/
end
Это будет рекурсивно искать путь и хранить все имена файлов, заканчивающиеся на .pdf в массиве.
Ответ 2
Попробуйте следующее:
Dir.glob("#{folder}/**/*.pdf")
что совпадает с
Dir["#{folder}/**/*.pdf"]
Если переменная папки - это путь к корневой папке, которую вы хотите выполнить.
Ответ 3
Если скорость вызывает беспокойство, предпочитайте Dir.glob
более Find.find
.
Warming up --------------------------------------
Find.find 124.000 i/100ms
Dir.glob 515.000 i/100ms
Calculating -------------------------------------
Find.find 1.242k (± 4.7%) i/s - 6.200k in 5.001398s
Dir.glob 5.249k (± 4.5%) i/s - 26.265k in 5.014632s
Comparison:
Dir.glob: 5248.5 i/s
Find.find: 1242.4 i/s - 4.22x slower
require 'find'
require 'benchmark/ips'
dir = '.'
Benchmark.ips do |x|
x.report 'Find.find' do
Find.find(dir).select { |f| f =~ /\*\.pdf/ }
end
x.report 'Dir.glob' do
Dir.glob("#{dir}/**/*\.pdf")
end
x.compare!
end
Используя ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin15]
Ответ 4
В качестве небольшого улучшения для ответа Джергасона и Мэтта, здесь, как вы можете конденсироваться до одной строки:
pdf_file_paths = Find.find('path/to/search').select { |p| /.*\.pdf$/ =~ p }
Это использует метод Find, как указано выше, но использует тот факт, что результат является перечислимым (и как таковой мы можем использовать select), чтобы получить массив обратно с набором совпадений