こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

perlプログラム 外部複数ファイルの読み込み処理について

perlプログラム 外部複数ファイルの読み込み処理について

あるフォルダに T0001_05_01,T0001_05_02,T0001_05_03,…,T0001_05_31 という31個のファイルがあります。
それぞれのファイルは 下記のような 形式で記述されております。
(例 T0001_05_01のファイルの中身)
2010-05-01 00:00:00.000 N00001 AAAAAA
2010-05-01 00:00:00.108 N00018 BBBBBB
2010-05-01 00:00:10.305 N00002 AAAAAA
2010-05-01 01:00:10.966 N00008 CCCCCC

また、別のlist.txtに 下記のようなユニークなリストが入っております。
AAAAAA
CCCCCC
WWWWWW

このとき、list.txtの値が それぞれT0001_05_XXファイルの何行目に出力されているか
出力するperlプログラムを作成したい。
(出力結果イメージ:1ファイル化)
T0001_05_01 1行目 2010-05-01 00:00:00.000 N00001 AAAAAA
T0001_05_01 3行目 2010-05-01 00:00:10.305 N00002 AAAAAA

T0001_05_31 10行目 2010-05-31 03:00:00.999 N00400 AAAAAA
T0001_05_01 4行目 2010-05-01 00:00:00.000 N00008 CCCCCC

perlプログラム知識がないものなので、このようなファイルの出力の仕方がわかりません。
教えていただけると助かります。

投稿日時 - 2010-06-01 18:39:17

QNo.5937712

すぐに回答ほしいです

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

サンプルプログラムを作成してみたので試してみてください。
テストしていないのでうまく行かないことがあるかも知れません。

use strict;
open FH, "list.txt" or die "Can't open list.txt: $!";
my @keyword = <FH>; chomp @keyword;
close FH;
my ($day, @result) = ('00');

while (++$day lt '32') {
my $file = "T0001_05_$day";
open FH, $file or die "Can't open $file: $!";
while (my $line = <FH>) {
foreach my $i (0 .. $#keyword) {
if ($line =~ /$keyword[$i]/) {
push @result, [$i, "$day", $., "$file ${.}行目 $line"];
last;
}
}
}
close FH;
}

@result = map { $_->[3] } sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] || $a->[2] <=> $b->[2] } @result;

open OUT, ">out.txt" or die "Can't open out.txt: $!";
print OUT @result;
close OUT;

投稿日時 - 2010-06-04 10:12:15

お礼

このプログラムで うまく解決できました。ありがとうございます。

投稿日時 - 2010-06-10 15:03:37

ANo.2

このQ&Aは役に立ちましたか?

12人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

まだ解決しませんか?
もしLinux なら grepの方が楽かも。(windowsでは不可です)
以下を データT0001_05~ファイルとlist.txtと同じ場所において
パーミションを705にして実行してください。
------------------------------------- ○○.cgi
#!/usr/bin/perl
$| = 1;
print "Content-type: text/html\n\n";

@files = glob("T0001_05_*");
open(IN,"list.txt");@keys=<IN>;close(IN); chomp @keys;
foreach(@keys){
print "<b>$_</b><br>\n";
@result = `grep -n "$_" @files`;
foreach(@result){
split(/:/,$_,3);
print "@_[0] @_[1]行目 @_[2]<br>\n";
}
print "<hr>\n";
}
exit;
--------------------------------------
htmlで出してます。適宜ブラウザ上でコピーしてください。

投稿日時 - 2010-06-09 21:35:04

お礼

ボリュームが多く何百万行もあるため、grep実行はすでに試みたのですが、処理時間がかかってしまいました。プログラム初心者のため このプログラム内容は今後の参考にさせていただきます。ありがとうございます。

投稿日時 - 2010-06-10 15:06:24

ANo.1

まず、それらのファイルが保存されているディレクトリを開く。
list.txtがあれば、それを開いてAAAAAなどのハッシュを作っておく。
ディレクトリにあるファイルの一覧を取得する。
それらを順番に開いて、そのファイルごとに一行ずつパターンマッチを行う。
AAA・・があれば、そのハッシュに、行数とその行のデータを配列で追加していく、
 配列のハッシュを作成する。
最後に、書き込み用ファイルを開いて書き込む。

たとえば、
$hash{'AAAAAA'}=[(T0001_05_01,1,2010-05-01 00:00:00.000 N00001),
         (T0001_05_01,3,2010-05-01 00:00:10.305 N00002)
             ]
とか、メモリーを消費するのでSEDなどストリームエディタを使うほうが早くて良いのだろうけど・・。

投稿日時 - 2010-06-01 21:16:09

お礼

処理速度がなかなか改善できず、この処理では数日処理でも完了しませんでした。やり方は今後の参考にさせていただきます。

投稿日時 - 2010-06-10 15:07:45

あなたにオススメの質問