-1

毎日、次のようなログ ファイルを取得します。

/home/ado/log/log.20130605

ログ ファイルには、アイテム ID と ID が販売された回数が含まれます。そして、毎日と毎週のランキングを作っています。

だから私はこのようなログリーダーを持っています

    #!/usr/bin/perl
    use strict;
    use warnings;
    use POSIX 'strftime';

    my $current_date = strftime "%Y%m%d", localtime;
    my $filename     = "/home/ado/log/log.$current_date";

    open my $file, "<", $filename or die("$!: $filename");
    while (<$file>) {
        if (/item_id:(\d+)\s*,\s*start/) {
            $output{$1}++;
        }
    }
    close $file;
    for my $item(keys %output) {
        print "$item -> $output{$item}\n";
    }

これをDBに保存します。

そして、これを毎日実行するために cron コマンドを使用します。これまでのところ、毎日ランキングを作成するためのすべてが揃っています。

しかし、毎週はどうですか?

これは、一度に 7 つのファイルを読み取る新しいスクリプトを作成することを意味します。

    /home/ado/log/log.20130603
    /home/ado/log/log.20130604
    /home/ado/log/log.20130605
    /home/ado/log/log.20130606
    /home/ado/log/log.20130607
    /home/ado/log/log.20130608
    /home/ado/log/log.20130609

そして正規表現を検索します。次に、cron を使用して毎週実行します。

ファイル名が常に変化していることに注意して、1 つではなく 7 つのファイルを読み取るようにスクリプトを変更するにはどうすればよいですか? – adriancdperu 4 分前編集

4

4 に答える 4

1

Time::Pieceを使用して、関連するすべてのファイル名を検索し、それら@ARGVをコマンド ライン パラメーターとして入力したかのように配置することをお勧めします。次に、を使用してそれらすべてから読み取ることができます<>

このような

use strict;
use warnings;

use Time::Piece;
use Time::Seconds 'ONE_DAY';

my $today = localtime;
@ARGV = grep {
  /\.(\d{8})$/ and
      $today - Time::Piece->strptime($1, '%Y%m%d') < ONE_DAY * 7;
} glob '/home/ado/log/log.*';

while (<>) {
  ++$output{$1} if /item_id:(\d+)[\s,]*start/;
}

printf "%s -> %s\n", $_, $output{$_} for sort keys %output;
于 2013-06-05T09:03:59.177 に答える
0

一連の入力ファイルを引数として取り、標準出力に書き込むプログラムを作成します。

引数として 7 つの毎日の入力ファイルを使用してプログラムを呼び出し、その標準出力を週ごとの要約にリダイレクトします。

summarize_files file1 file2 file3 file4 file5 file6 file7 > weekly.summary

同じプログラムを 1 つの日次入力ファイルで使用して、その標準出力を日次要約にリダイレクトすることもできます。

summarize_files file1 > daily.summary

入力ファイルの名前を生成するために、日単位で指定された今日の日付からの 2 つのオフセットの間のファイル名を使用するように調整することもできます。

 summarize_files -7 -1 > weekly.$(date +%Y%m%d)
 summarize_files -1 -1 > daily.$(date +%Y%m%d)
于 2013-06-05T07:47:13.593 に答える
0

スレッドの使用 も役立ちます。

#!/usr/bin/perl

use strict;
use warnings;
use threads;

my ($fh1, $fh2, $fh3, $fh4, $fh5, $fh6, $fh7);
my $thr1 = threads->new(\&sub1, "file1", $fh1);
my $thr2 = threads->new(\&sub1, "file2", $fh2);
my $thr3 = threads->new(\&sub1, "file3", $fh3);
my $thr4 = threads->new(\&sub1, "file4", $fh4);
my $thr5 = threads->new(\&sub1, "file5", $fh5);
my $thr6 = threads->new(\&sub1, "file6", $fh6);
my $thr7 = threads->new(\&sub1, "file7", $fh7);

$thr1->join();
$thr2->join();
$thr3->join();
$thr4->join();
$thr5->join();
$thr6->join();
$thr7->join();

sub sub1 {
    my ($file, $fh) = @_;

    my %output;
    open $fh, "<", $file or die("$!: $file");
    while (<$fh>) {
          if (/item_id:(\d+)\s*,\s*start/) {
              $output{$1}++;
          }
    }
    close $fh;
    for my $item (keys %output) {
        print "$item->$output{$item}\n";
    }
}
于 2013-06-05T09:52:10.183 に答える