• ベストアンサー

ファイルの中身に対する再帰的検索

初心者です。 テキストファイルの中身を調べて、その中に特定の拡張子を持ったファイル名があれば更にその中身を調べていって、階層構造になったファイルを全て調べあげるスクリプトを作ろうとしています。 例えばfile1.txtの中身が ... hoge file2.txt file3.txt hogehoge ... だったとすれば、今度はfile2.txtおよびfile3.txtの中身に.txtという拡張子を持ったファイル名があるかどうか調べ、該当するものが無くなるまで調べていきます。 これらのテキストファイルは全て同じディレクトリ内に存在します。 どういう具合のループにすればよいのか想像がつきません。 アドバイスお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • moon_piyo
  • ベストアンサー率60% (88/146)
回答No.1

こんにちは ループを二重にしてみました $dir = "c:\\temp"; $ext = "txt"; $start = "file1.txt"; @buf1 = ($start); while (@buf1) { @buf2 = (); foreach $file (@buf1) { next if (++$cunt{lc($file)} > 1); open(F, "<$dir\\$file") || next; print STDERR "$file Open!!\n"; while (<F>) { if (($newfile) = lc =~ /^\s*(.+\.$ext)\s*$/) { push(@buf2, $newfile); } } close(F); } @buf1 = @buf2; }

GT_Max
質問者

お礼

ありがとうございます。配列にファイル名をどんどん追加していくわけですね。 案外単純な具合にできるものなんですね。非常に勉強になりました。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「新しいファイル」に対する処理をいつ行うのかにもよりますが, 「現在のファイルを処理してから」ということであれば my @files = ('file1.txt'); my %read; while (@files) { my $file = shift @files; next unless $read{$file}++; open(my $fh, $file); while (my $line = <$fh>) { (chomp($line), push @files, $line and next) if $line =~ /\.txt$/; $line に対して何か処理 } close($fh); } のような感じでできるかもしれません. 「新しいファイルを見付けたらすぐ処理する」方針だと再帰ですね. ちなみに動作チェックはしてません.

GT_Max
質問者

お礼

ご回答ありがとうございます。 ファイルを処理するタイミングはいつでもよいので、ご回答いただいたやり方で全く問題ないです。 参考になります。

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.2

こんな感じでサブルーチンの再帰呼び出しをしてみたらどうでしょうか?(動作チェックしてないです。) 1つ問題となるのは、例えば、file2.txtにfile3.txtと書いてあって、file3.txtにfile2.txtと描いてあった場合に、無限ループに陥るので何らかの対策が必要です。(下のサンプルでは、ハッシュを使ってチェックすることにしてみました。) my %duplicate; &read("file1.txt"); sub read{ my @files = @_; if(@files == 0){ return; } # 新しいファイルを開いて次のターゲットを探す my @nextFiles; foreach my $file(@files){ open IN, $file or die "cannot open $file: $!"; while(<IN>){ if(m/\.txt$/){ unless(exists $duplicate{$_}){ push @nextFiles, $_; $duplicate{$_} = 1; } } } close IN; } # 再帰呼び出し &read(@nextFiles); }

GT_Max
質問者

お礼

おっしゃるとおり、無限ループになる可能性がありますね。 質問投稿時には気がつきませんでした。 ご指摘、そしてご回答まことにありがとうございます。

関連するQ&A

専門家に質問してみよう