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

perl 超!初心者です。同一データの数え上げ。

あまり上手く説明できませんがよろしくお願いします。
ある行から行までの同一データを数え上げる処理をしたいです。
例えば、以下のようなデータがあるとします。
---------------------
<NAME>
田中
佐藤
佐藤
山田
田中
<NAME>
佐藤
田中
渡辺
渡辺
佐藤
-------------------
while (<>){
$linecount{$_}++;
}
foreach $line (sort{$linecount{$b} <=> $linecount{$a}}keys%linecount)
{
print $linecount{$line},"",$line if($linecount{$line} >= 1);
}
これで、行の重複回数と、データを出力はできたのですが、
さらに、<NAME>で区切ってそれぞれの区分で同一データの数を数えていきたいです。結果としては

<NAME>
2 田中
2 佐藤
1 山田
<NAME>
2 渡辺
2 佐藤
1 田中

と出力したいのですが、どうすればよいでしょうか?

A 回答 (2件)

こういうやり方もあるということで。



#!/usr/bin/perl
use strict;
use warnings;
use Fatal qw(:void open close);
use feature ':5.10';


$/ = "<NAME>\n";

while (my $record = <DATA>) {
my %h;
chomp $record;
next if ($record eq '');
foreach my $item (split qq{\n}, $record) {
$h{$item}++;
}
printf("%2d %s\n", $h{$_}, $_) for (sort {$h{$b}<=>$h{$a}} keys %h);
printf "=====\n"
}


__END__
<NAME>
田中
佐藤
佐藤
山田
田中
<NAME>
佐藤
田中
渡辺
渡辺
佐藤

実行結果:
2 田中
2 佐藤
1 山田
=====
2 佐藤
2 渡辺
1 田中
=====

二番目の名前の並びがちと期待通りではないですね。
    • good
    • 0
この回答へのお礼

私も、「$/ = "<NAME>\n";」を使って試してみたのですが、上手くいかなかったのですが、このようにするのですね。大変勉強になりました。ありがとうございました。

お礼日時:2008/11/14 00:49

"<NAME>"がある行と末尾行が来たら、カウンタの出力とリセットを実行すれば良いのでは?



my %linecounts; #グローバル変数化
-------------------
while (<>)
{
    if($_ eq '<NAME>')
    {
        &present_counter();#NAME行
        next;
    }
    $linecount{$_}++;
}
&present_counter();#末尾用

-------------------
sub present_counter()
{
    foreach $line (sort{$linecount{$b} <=> $linecount{$a}}keys%linecount)
    {
        print $linecount{$line}," ",$line if($linecount{$line} >= 1);
    }
    undef %linecounts;#クリア
}
    • good
    • 0
この回答へのお礼

このようなやり方もあるのですね。大変勉強になります。
ありがとうございました。

お礼日時:2008/11/14 00:50

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