• ベストアンサー

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

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

  • Perl
  • 回答数3
  • ありがとう数4

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

  • ベストアンサー
  • 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

  • ファイル名に親フォルダ名をつけたい

    お世話になります。 VBScriptで、下記のような動きをさせたいのですが、 私の頭では全くわかりませんので、ご知識ある方 何卒よろしくお願いします。 Scriptを実行すると、「対象のテキストファイル」の 名前を「親のフォルダ名+"_"+対象のテキストファイル名」 にしたいのです。 例えば、 hogeフォルダに、 「複数のテキストファイル(拡張子.txt)」 「batファイル」 を置いて、 batファイルを実行すると、 現在のテキストファイルの名前の前に,親のフォルダ名をつけたいという 形です。 ※元のテキストファイル名が,「1.txt」なら「hoge__1.txt」にしたい インターネットで、いろいろ調べたのですが、断片的な情報では、 私の頭ではまったくわかりませんでした。。 そこで、大変申し訳ないのですが、実際に動くソースレベルで 教えて頂きたいので、ご知識ある方、何卒よろしくお願い致します。

  • c++でファイル名から数字をテキストファイルに取り

    hogehoge_1_1_1.txt hogehoge_1_2_3.txt というファイル名であった場合、 hogehoge_1_1_1.txtからは1 1 1 hogehode_1_2_3.txtからは1 2 3 というふうにファイル名の他に数値もテキストファイルに出力したい場合どのようにすればできるでしょうか? このように単純な作業なのですが、 このような形式のテキストファイルが大量にあって、まとめて処理してグラフなんかを作成したいために質問させていただきました。 回答よろしくお願いします。 補足 説明が不足していましたが、実行ファイルと同じフォルダに入れたテキストファイル等すべてから、ファイル名を指定しないで数値の部分だけを取り出すようにするにはどうしたらいいかも知りたいです。 分かりにくい説明かもしれませんが、回答よろしくお願いします。

  • テキストファイルの中身について

    あるフォルダしたのテキストファイルとそのファルダしたのフォルダ中のテキストファイルについて、 例えば、”日本”と言う文字が有ったら、そのテキストファイル名を表示するようなの機能を実現したいです。 何を使ったら、いいですか? サンプルが欲しいです。 教えてください!お願いします。 ーーーーーーーーーーーーー temp-------a.txt |------b.txt |------temp1 |--------a1.txt |--------b1.txt       … などなど、 テキストファイルの中身に、”日本”という文字が存在したら、そのテキストファイル名を出力 ーーーーーーーーーーーーー

  • サブディレクトリ名、フォルダ構造のみをテキスト出力したい

    ディレクトリ以下のサブフォルダ、 階層5階層ぐらいまでですが、それらを全て テキストに出力、もしくはテキストにコピペしたいです。 ファイルをコピーしなくて、ディレクトリをコピーしなくて、ディレクトリ「名」のみクリップボードか、TXTに記録できるものを探しています。 できればフルパスでの場合と、フルパスじゃなくフォルダ名のみをコピーできる場合、分けてできるソフトがベストです。 サブフォルダも分析してくれるというのをとにかく探しています。フォルダの「構造」には特に拘っていません、フルパスでそれは十分なんですが・・ よろしくお願いします。

  • ファイル検索

    こんにちは。質問させてください。 あるフォルダ(ここでは$dir = "c:\\test\\file_data\\"とでもしておきます。)内に テキストファイルが複数存在するとします。 test1218.01.file1.txt test1218.10.file1.txt test1218.11.file1.txt test1219.01.file1.txt test1219.10.file1.txt test1219.11.file1.txt test1219.01.file2.txt test1219.10.file2.txt test1219.11.file2.txt 上記のようなファイル名のテキストファイルが存在したとします。 それでこのテキストファイルのうち、以下のファイルの内容を画面に表示したいと 考えています。 test1219.01.file1.txt test1219.10.file1.txt test1219.11.file1.txt 1219(今日の日付という意味), file1(一回目のファイルという意味)で 構成された上記のファイルを指定されたディレクトリ($dir)以下で 検索し上記のファイル名を取得し、また取得したファイルの中身を 表示するロジックを考えています。 ひとつのファイルを取得することはできたのですが、 複数となる(上記の場合は3つ当てはまることはわからないので 指定する日付などで取得ファイル数がかなりことなる)ため うまく書くことができません。 どなたかいいロジックなどをお持ちでしたら ぜひ伝授していただけたらと考えています。 どうかよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • perlを使ったファイルの入出力について

    perl 初心者です。 perl を使ってデータ整理を試みていますが、方法がわからなくて困っています。 やりたい操作は、 1、ディレクトリ内にある特定の拡張子をもつすべてのデータファイルを読み込む 2、データソート 3、データファイル名を変更せずに、ソートしたデータを出力する 例 ディレクトリに以下のデータファイルがあるとします aaa.data bbb.data ccc.data : zzz.data これらのデータファイルをすべて読み込み、中身を整理した後に aaa.txt bbb.txt ccc.txt : zzz.txt となるように、それぞれのデータの名前を変更せずに出力したいと思っています。 スクリプトのサンプルなんかがあればありがたいです。

    • ベストアンサー
    • Perl
  • シェルスクリプト while read lineにつきまして

    シェルスクリプトについて、各行の値を使って、更新したいと考えています。 引数を2つ持たせて、2つともファイルです。 ファイル名1には、 test1 test2 test3 のディレクトリを記載し、 ファイル名2には、 test4.txt test5.txt test6.txt のテキストを記載します。 例) 引数1 ファイル名1 引数2 ファイル名2 while read lineをどのように使ったら良いかわからないのですが、 ファイル名1を1行ずつ読み込んで、 読み込んだディレクトリをファイル名2に書かれているテキストを更新します。 具体的にやりたいと思っている内容ですが、 ・cd ファイル名1の1行目ディレクトリ ・svn up ファイル名2のテキスト ここをファイル名2に書かれている行分ループして 上記svn upコマンドを実行します。 ・ファイル名2に書かれている行分ループ完了後、 ファイル名1の2行目にかかれているディレクトリを読み込んで、 cd ファイル名1の2行目ディレクトリ ・svn up ファイル名2のテキスト ここをファイル名2に書かれている行分ループ。 という形のシェルスクリプトを作成したいと思っています。 上手く説明できないのですが、このようなことが出来るのかお教えいただけますでしょうか。 出来るのであれば、どのようにすればできるのかご教授いただけると幸いです。 宜しくお願い致します。

  • 任意のディレクトリ以下に存在するファイル数について

    任意のディレクトリ以下に存在するファイルを数える方法について教えて下さい。 現在、あるディレクトリ以下にある特別な命名規則のファイルを探し、リネーム or読み込みを行うような処理を考えています。 例 /* *********************************************************************** */ ☆あるディレクトリ以下に・・・    aaaaa.txt    b.log    AAA_hogehoge.txt    BBB_hogehoge.txt    CCC_hogehoge.txt      ^^^^^^^^^^^^ここの部分は共通  があったとすると、AAA_hogehoge.txt読み込み→BBB_hogehoge.txt読み込み →CCC_hogehoge.txt読み込み。 ☆あるディレクトリ以下に・・・    DDD_hogehoge.txt  のみがあったとすると、DDD_hogehoge.txt→hogehoge.txtへリネーム。 /* *********************************************************************** */  上記の例のような事を考えています。その際「任意のディレクトリ以下に存在する 特定パターンに合致するファイル数(*hogehoge.txtで掛かるファイル数)とファイル名が 欲しいのです。 何か良い方法、使える関数等がありましたら教えて下さい。 なおOSはLinux、ソラリス、コンパイラはgccを考えています。

  • 検索文字列以外のファイル

    テキストファイルの中身を検索して、その文字列以外のファイル名を取りたいのです。具体的には、 【A.txtの中身】 123 abc 【B.txtの中身】 111 abc 【C.txtの中身】 222 abc このようなテキストファイルの中身を検索して、文字列「123 abc」以外が書かれているファイル名(つまり、B.txt、C.txt)を取得したいのですが、findstrやForなどを駆使すれば、できますでしょうか?

  • 特定ディレクトリ以下の複数のフォルダ名とファイル名を一括で連番にするバッチの作成

    特定のフォルダ(ディレクトリ)以下の複数のフォルダ名とファイル名を 一括で連番にしてくれる方法(連番+拡張子のリネーム)を教えてください。 ソフトでは簡単ですが*.bat ファイルで実行するスクリプトを 知りたいので宜しくお願い致します 例えば フォルダ0 ├フォルダ1 │ ├ a.txt │ ├ b.jpg │ └ フォルダ2 │    └c.exe └ フォルダ3   └ d.exe という構造があったとして 000000 ├000001 │ ├ 000000.txt │ ├ 000001.txt │ └ 000000 │    └000000.txt └ 000002   └ 000000.txt この様に特定ディレクトリ以下の複数のフォルダ名とファイル名を連番 (上記は6桁ですが001,002…など3桁などに対応できる)にしたいのです 以下の方法で特定のフォルダ内のファイルを.txtに変更まではできましたが、 特定のフォルダより下層のファイルを.txtに変更はできませんでした。 REN E:\フォルダ\フォルダ\*.* *.txt 上記のスクリプトは特定フォルダにあるファイルは拡張子の変更が出来ますが、 そのフォルダより下層の複数のフォルダ名とファイル名の拡張子の変更をできないので、 *.batファイルで連番+拡張子のリネームを一括でするスクリプトの明記をお願い致します。 ご存知の方、どの様なご意見でも構いませんので ご回答頂けると幸いです。宜しくお願い致します。

専門家に質問してみよう