電子書籍の厳選無料作品が豊富!

テキストファイルをperlを使用して下記のように
変換したいと思っています。

---------------------------
【変換前】
aaa 8000 52 ---1行目
abc 200 48 ---2行目
cbd 250 31   ---3行目
efg 98 45   ---4行目
abc 390 68   ---5行目
ddd 89 90   ---6行目
aaa 65 40   ---7行目
fed 900 66   ---8行目
efgh 99 49 ---9行目
abc 40 40 ---10行目

【変換後】
aaa 8000 52   ---1行目
cbd 250 31   ---3行目
efg 98 45   ---4行目
abc 390 68   ---5行目
ddd 89 90   ---6行目
fed 900 66   ---8行目
efgh 99 49 ---9行目
----------------------------

やりたいことはまず行の先頭文字列(aaaやabc)が完全に一致する行が
複数あれば(2,5,10行目のabcや1,7行目のaaa)、2番目の文字列(スカラー値)の値が
小さい方の行は出力しないようにしたいと思っています。

例えば上記の場合ですと、2,5,10行目の最初の文字列はaaaで完全に一致しており、
2番目の列の値は5行目が390に対し、2行目は200、10行目は40と小さくなっているため
2行目,10行目は出力されない、というのが望んでいる動作です。

sortを使用してどうにかならないかとも、考えたのですが
そこから先がどうしていいか思いつきませんでした。

何かよい方法を思い浮かぶ方がいましたら、どのようにPerlで記述すればよいのか
教えて頂けないでしょうか?

宜しくお願いいたします。

A 回答 (2件)

ソートには「シュウォーツ変換」と呼ばれるやり方があります。

ネット上にはたくさんの情報がありますので参照してください。次のプログラムは、1行に1処理で書いています。

use strict;
my @data;
push @data, [$_, $., split /\s+/] while <DATA>;
@data = sort { $a->[2] cmp $b->[2] or $b->[3] <=> $a->[3] } @data;
@data = @data[0, grep { $data[$_ - 1]->[2] ne $data[$_]->[2] } 1 .. $#data];
@data = sort { $a->[1] <=> $b->[1] } @data;
@data = map { $_->[0] } @data;
print @data;

__DATA__
aaa 8000 52
abc 200 48
cbd 250 31
efg 98 45
abc 390 68
ddd 89 90
aaa 65 40
fed 900 66
efgh 99 49
abc 40 40
    • good
    • 0
この回答へのお礼

ありがとうございます。
試してみたところ所望の結果が得られました。
非常に助かりました。

お礼日時:2011/08/04 23:44

1つの例:


とりあえず最初の欄の文字列をキーにするハッシュを作る.
その結果を, 今度は行番号をキーにするハッシュに入れて print.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!