Поиск в папке и во всех ее подпапках файлов определенного типа - PullRequest
65 голосов
/ 17 августа 2010

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

Ответы [ 4 ]

102 голосов
/ 17 августа 2010

Попробуйте это:

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

, что совпадает с

Dir["#{folder}/**/*.pdf"]

Где переменная папки - это путь к корневой папке, по которой вы хотите выполнить поиск.

60 голосов
/ 17 августа 2010

Вы хотите модуль Find . Find.find принимает строку, содержащую путь, и передает родительский путь вместе с путем каждого файла и подкаталога в сопровождающий блок. Пример кода:

require 'find'

pdf_file_paths = []
Find.find('path/to/search') do |path|
  pdf_file_paths << path if path =~ /.*\.pdf$/
end

Это будет рекурсивно искать путь и сохранять в массиве все имена файлов, заканчивающиеся на .pdf.

22 голосов
/ 15 апреля 2016

Если скорость имеет значение, предпочитайте 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]

11 голосов
/ 28 апреля 2015

В качестве небольшого улучшения ответа Джергасона и Мэтта выше, вот как вы можете сжать одну строку:

pdf_file_paths = Find.find('path/to/search').select { |p| /.*\.pdf$/ =~ p }

При этом используется метод Find, как указано выше, но используется тот факт, что результатперечислимый (и поэтому мы можем использовать select), чтобы вернуть массив с набором совпадений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...