• ベストアンサー

Perl初心者です。同一データを数えるには

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 田中 と出力したいのですが、どうすればよいでしょうか?

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.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 田中 ===== 二番目の名前の並びがちと期待通りではないですね。

sonosono08
質問者

お礼

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

その他の回答 (1)

回答No.1

"<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;#クリア }

sonosono08
質問者

お礼

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

関連するQ&A

専門家に質問してみよう