我每天都会得到一个日志文件,如:
/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";
}
我将其保存在数据库中。
我使用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每周运行一次。
如何修改脚本以读取7个文件而不是1个,注意文件名不断变化? - adriancdperu 4分钟前编辑
答案 0 :(得分:1)
在文件处理周围添加了循环,并在此之前收集所有日志文件,
#!/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";
my @filenames = reverse sort glob("/home/ado/log/log.*");
if (@filenames > 7) { $#filenames=6; }
for my $filename (@filenames) {
my %output;
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";
}
}
答案 1 :(得分: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;
答案 2 :(得分:0)
编写以一组输入文件作为参数的程序,并写入标准输出。
使用7个每日输入文件作为参数调用程序,并将其标准输出重定向到每周摘要。
summarize_files file1 file2 file3 file4 file5 file6 file7 > weekly.summary
您可以将同一程序与每日输入文件一起使用,并将其标准输出重定向到您的每日摘要。
summarize_files file1 > daily.summary
您还可以安排在今天的日期(以天为单位)的两个偏移之间使用文件名来生成输入文件的名称:
summarize_files -7 -1 > weekly.$(date +%Y%m%d)
summarize_files -1 -1 > daily.$(date +%Y%m%d)
答案 3 :(得分:0)
使用threads也很有用!
#!/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";
}
}