每周我都想通过每日日志(在红帽系统上)解析,并在IP地址列上获取一些统计信息。每日日志包含
的数据<device>,<ip>,<city>,<packets>
这样:
样本数据 - 一条日志的前5行:
gw1,25.0.10.61,houston,50
gw1,25.0.20.61,dallas,30
gw1,25.0.30.60,ftworth,80
gw1,25.0.10.61,houston,40
gw1,25.0.10.62,houston,40
我想浏览所有七个日志,并确定每个IP地址的数据包总数。
所需的输出将为
<ip>,<packet_count>
从所有七个日志中的数据包计数排序:
25.0.10.61,480
25.0.10.62,400
25.0.30.60,220
等。
我不太确定哈希是否是这样做的最佳方法,如果是这样,则如何处理。
您可以将哈希用于数据。
代码:
my $filename ="log.txt"; #provide your filename here
open FH, $filename or die "Errorn";
my %myhash;
while(<FH>)
{
chomp($_);
my @arr = split(/,/, $_);
$myhash{$arr[1]} +=$arr[3];
}
#access the hash
foreach my $ip (keys %myhash)
{
print "$ipt$myhash{$ip}n";
}
作为单线:
perl -F, -lane '
$count{$F[1]} += $F[3]
} {
while (($ip,$n) = each %count) {print "$ip,$n"}
' file*.log | sort -t, -k2,2nr
排序可以在perl中进行,但比这更长。
} {
的窍门是将仅在输入末尾运行的代码分开每行应执行的代码。那个单线转化为:
BEGIN { $/ = "n"; $ = "n"; }
LINE: while (defined($_ = <ARGV>)) {
chomp $_;
our @F = split(/,/, $_, 0);
$count{$F[1]} += $F[3];
}
{
while (($ip, $c) = each %count) {
print "$ip,$c";
}
}
您不说如何获取日志文件的名称。该解决方案仅使用glob
在当前目录中找到以.log
结尾的所有文件的名称。将此列表分配给@ARGV
使我们可以在没有明确打开的情况下直接读取所有文件,就像在命令行上输入了它们的名称
i保留一个hash %data
,其密钥是IP地址,值是数据包计数的累积总数。我还保持宽度值$w
,这是迄今为止遇到的最长IP地址的长度。这在printf
中用于使列整齐地对齐
输出的顺序是在最终for
环内的简单排序完成的
use strict;
use warnings 'all';
@ARGV = glob "*.log";
my %data;
my $w;
# <device>,<ip>,<city>,<packets>
while ( <> ) {
s/s+z//;
my ($ip, $count) = (split /,/)[1,3];
$data{$ip} += $count;
my $len = length $ip;
$w = $len unless $w and $w >= $len;
}
for my $ip ( sort { $data{$b} <=> $data{$a} } keys %data ) {
printf "%*s %dn", $w, $ip, $data{$ip};
}
输出
25.0.10.61 90
25.0.30.60 80
25.0.10.62 40
25.0.20.61 30
这是我要这样做的方法:
use strict;
use warnings;
my $packetCountByIP = {};
for (my $i = 1; $i <= 7; ++$i) {
my $fileName = 'activity'.$i.'.log';
my $fh;
if (!open($fh,'<',$fileName)) { die("$fileName: $!"); }
while (my $line = <$fh>) {
my $fields = [split(',',$line)];
my $ip = $fields->[1];
my $packetCount = $fields->[3]+0;
$packetCountByIP->{$ip} += $packetCount;
} ## end while (log file lines)
close($fh);
} ## end for (log files)
my $ips = [sort({$packetCountByIP->{$b}<=>$packetCountByIP->{$a}} keys(%$packetCountByIP))];
foreach my $ip (@$ips) {
print("$ip,$packetCountByIP->{$ip}n");
} ## end foreach (ips)