Подтвердить что ты не робот

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

Я пытаюсь найти все файлы определенного типа (например .pdf) в данной папке и скопировать их в новую папку. То, что мне нужно, это указать корневую папку и выполнить поиск по этой папке и всем ее подпапкам для любых файлов, которые соответствуют данному типу (.pdf). Может кто-нибудь дать мне руку на то, как я должен искать вложенные папки корневой папки и их подпапки и так далее. Похоже, что рекурсивный метод мог бы сделать трюк здесь, но я не могу реализовать его правильно? (Я, кстати, реализую эту программу в рубине).

4b9b3361

Ответ 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), чтобы получить массив обратно с набором совпадений