以前に、ディレクトリをオープンしてファイル名を読む - Ruby入門勉強ルームで、ディレクトリを再帰的に走査するために、再帰関数を作ってみた。
しかし、再帰関数を書くよりも、Dir.globやFind.findを使ったほうが簡単です。
以下のような構造のディレクトリを走査してみます。
C:\ROOT_DIR
│ bar.rb
│ baz.rb
│ foo.rb
│
└─sub_dir
│ sub_bar.rb
│ sub_baz.rb
│ sub_foo.rb
│
└─sub_sub_dir
sub_sub_bar.rb
sub_sub_baz.rb
sub_sub_foo.rb
Dir.globとFind.findを使ったディレクトリ走査コード
# ディレクトリを再帰的に抽出する require 'find' require 'pp' root = "C:/root_dir" # Dir.globの場合、エントリの配列が返る puts "--- Dir.glob ---" dir_entries = Dir.glob(root + "/" + "**/*") pp dir_entries # Find.findは、走査を行う。findをrequireして使う。 puts "--- Find.find ---" find_entries = Array.new Find.find(root) do |path| find_entries.push(path) end pp find_entries
実行結果
--- Dir.glob --- ["C:/root_dir/bar.rb", "C:/root_dir/baz.rb", "C:/root_dir/foo.rb", "C:/root_dir/sub_dir", "C:/root_dir/sub_dir/sub_bar.rb", "C:/root_dir/sub_dir/sub_baz.rb", "C:/root_dir/sub_dir/sub_foo.rb", "C:/root_dir/sub_dir/sub_sub_dir", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_bar.rb", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_baz.rb", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_foo.rb"] --- Find.find --- ["C:/root_dir", "C:/root_dir/sub_dir", "C:/root_dir/sub_dir/sub_sub_dir", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_foo.rb", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_baz.rb", "C:/root_dir/sub_dir/sub_sub_dir/sub_sub_bar.rb", "C:/root_dir/sub_dir/sub_foo.rb", "C:/root_dir/sub_dir/sub_baz.rb", "C:/root_dir/sub_dir/sub_bar.rb", "C:/root_dir/foo.rb", "C:/root_dir/baz.rb", "C:/root_dir/bar.rb"]
Find.find を使った場合、基点にしたパス(C:/root_dir)も含まれるようです。
Dir.globで使っている「**/*」は、ディレクトリを再帰的にたどってマッチを行うための指定。
Dir - Rubyリファレンスマニュアル**/ ワイルドカード */ の0回以上の繰り返しを意味し、 ディレクトリを再帰的にたどってマッチを行います。 例えば, foo/**/bar は foo/bar, foo/*/bar, foo/*/*/bar ... (以下無限に続く)に対してそれぞれ マッチ判定を行います。
■この記事のトラックバックURL:
http://www.mapee.jp/mpe334/mt-tb.cgi/495