1

セリフの読み方など、何度も質問してすみません。私はたまたま、次のような巨大な (500,000 行) ファイルを扱っています。

2013-05-27T19:01:23 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:29 [INFO] item_id:2, pause at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23

私がする必要があるのは、入力としてファイルの場所を指定して、出力が次のようなスクリプトを作成することです。

$output = [ {item_id => 1, counter => 2 }, { item_id...... 

つまり、各 item_id は、配列参照内にある開始の数とペアにする必要があります。ファイルが大きすぎるため、「while」を使用してファイルを複数回読み取ることはできないことに注意してください。また、アイテムがいくつあるかアプリオリにはわかりません。

Stackoverflowメンバーからのヒントを参考に書いた方法は以下の通りです。

sub count_start{
open LOGFILE, $file_location;
my $max;
my $i;
my $counter = 0;
my $found = 0;
my $data;

while (<LOGFILE>) {
  next unless /item_id:(\d+)/;
  $found = $1 if $found < $1;

  for ($i =1, $i<=$found, $i++){
   if ($file_location =~ /\bitem_id:$i, start\b/ig){
   $counter++;
   }
  $output = [ $i => $counter ];
  } 
}
close LOGFILE;
return $output;
}
1;

しかし、すべてが本当にうまくいきませんでした:(.私は多くの厄介な警告を受け取り、私が求められたものとほとんど似たものは何もありません.何かアイデアや提案はありますか?

この perl 初心者のひどいコードを許してください。

4

2 に答える 2

1

ハッシュを使用してカウントを行い、その後ハッシュの配列に変換します。ただし、perl コードを使用してデータを保存しているように見えますが、これは最善の方法ではありません。JSON、さらには など、より優れた形式がありますText::CSV

それはさておき、Data::Dumperモジュールはこの目的に使用できます。

use strict;
use warnings;
use Data::Dumper;

my %output;

while (<DATA>) {
    if (/ item_id:(\d+), start at /) {
        $output{$1}++;
    }
}

my @data = map { { item_id => $_, counter => $output{$_} } } keys %output;
print Dumper \@data;


__DATA__
2013-05-27T19:01:23 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:29 [INFO] item_id:2, pause at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:1, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:3, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23
2013-05-27T19:01:30 [INFO] item_id:5, start at Reader.pm line 23

出力:

$VAR1 = [
          {
            'counter' => 5,
            'item_id' => '1'
          },
          {
            'counter' => 3,
            'item_id' => '3'
          },
          {
            'counter' => 5,
            'item_id' => '5'
          }
        ];

ハッシュがソートされていないため、出力はソートされていないことに注意してください。並べ替えたい場合は、sort関数をキーに適用できます。

また、このバージョンでは、「開始」をカウントすると言ったことが考慮されていることに注意してください。この入力には、item_id:2, pause at.

于 2013-05-28T05:56:30.767 に答える