web-dev-qa-db-ja.com

フォルダーとそのすべてのサブフォルダーで特定の種類のファイルを検索する

特定のフォルダー内の特定のタイプ(.pdfなど)のすべてのファイルを検索し、それらを新しいフォルダーにコピーしようとしています。ルートフォルダを指定し、そのフォルダとそのすべてのサブフォルダを検索して、指定されたタイプ(.pdf)に一致するファイルを検索する必要があります。ルートフォルダーのサブフォルダーやそのサブフォルダーなどを検索する方法を教えてください。ここでは再帰的な方法でうまくいくように思えますが、正しく実装できませんか? (私はこのプログラムをRubyところで)で実装しています)。

65
agentbanks217

Find モジュールが必要です。 Find.findは、パスを含む文字列を受け取り、親ファイルのパスと各ファイルおよびサブディレクトリのパスを付随するブロックに渡します。いくつかのサンプルコード:

require 'find'

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

これは再帰的にパスを検索し、.pdfで終わるすべてのファイル名を配列に保存します。

60
jergason

これを試して:

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

と同じです

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

Folder変数は、検索するルートフォルダーへのパスです。

102
rogerdpack

速度が懸念される場合は、_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]を使用する

22
Dennis

上記のJergasonとMattの回答に対する小さな改善として、1行に凝縮する方法は次のとおりです。

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

これは上記のFindメソッドを使用しますが、結果が列挙可能であるという事実を活用し(したがってselectを使用できます)、一致のセットで配列を取得します

11
chrisdurheim