string – 在Perl中解析Apache日志
更新于5-10-2013
好的,现在我可以毫无问题地过滤掉IP地址.现在接下来我要做的下三件事我认为可以通过sort($keys)轻松完成,但我错了,然后尝试下面稍微复杂的方法似乎也不是解决方案.我需要做的下一件事是收集日期和浏览器版本.我将提供我的日志文件格式和我当前代码的示例. APACHE LOG 24.235.131.196 - - [10/Mar/2004:00:57:48 -0500] "GET http://www.google.com/iframe.php HTTP/1.0" 500 414 "http://www.google.com/iframe.php" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)" 我的守则 #!usr/bin/perl -w use strict; my %seen = (); open(FILE,"< access_log") or die "unable to open file $!"; while( my $line = <FILE>) { chomp $line; # regex for ip address. if( $line =~ /(d{1,3}.d{1,3})/ ) { $seen{$1}++; } #regex for date an example is [09Mar2009:05:30:23] if( $line =~ /[[d]{2}.*[d]{4}:[d]{2}:[d]{2}]*/) { print "nn $line matched : $_n"; } } close FILE; my $i = 0; # program bugs out if I uncomment the below line,# but to my understanding this is essentially what I'm trying to do. # for my $key ( keys %seen ) (keys %date) { for my $key ( keys %seen ) { my ($ip) = sort {$a cmp $b}($key); # also I'd like to be able to sort the IP addresses and if # I do it the proper numeric way it generates errors saying contents are not numeric. print @$ip->[$i] . "n"; # print "The IPv4 address is : $key and has accessed the server $seen{$key} times. n"; $i++; } 解决方法
你很亲密.是的,我会使用哈希.它通常被称为“看见哈希”.
#!usr/bin/perl use warnings; use strict; my $log = "web.log"; my %seen = (); open (my $fh,"<",$log) or die "unable to open $log: $!"; while( my $line = <$fh> ) { chomp $line; if( $line =~ /(d{1,3})/ ){ $seen{$1}++; } } close $fh; for my $key ( keys %seen ) { print "$key: $seen{$key}n"; } 这是一个包含一些输出的示例日志文件: $cat web.log [Mon Sep 21 02:35:24 1999] some msg blah blah [Mon Sep 21 02:35:24 1999] 192.1.1.1 [Mon Sep 21 02:35:24 1999] 1.1.1.1 [Mon Sep 21 02:35:24 1999] 10.1.1.9 [Mon Sep 21 02:35:24 1999] 192.1.1.1 [Mon Sep 21 02:35:24 1999] 10.1.1.5 [Mon Sep 21 02:35:24 1999] 10.1.1.9 [Mon Sep 21 02:35:24 1999] 192.1.1.1 $test.pl 1.1.1.1: 1 192.1.1.1: 3 10.1.1.9: 2 10.1.1.5: 1 我要注意的一些事情: 我的@array =< FH> ;;这会将整个文件拉入内存,这不是一个好主意.特别是在这种情况下,对于日志文件,它们可以变得非常大.如果没有正确旋转,更是如此. for或foreach会遇到同样的问题.同时是从文件中读取的最佳实践. 您应该养成使用3-arg词法范围打开的习惯,如上例所示. 你的死亡陈述不应该那么“精确”.看到我的消息.既然原因可能是权限,不存在,锁定等等…… UPDATE 这适用于您的日期. my $line = '[09Mar2009:05:30:23]: plus some message'; #example is [09Mar2009:05:30:23] if( $line =~ /([[d]{2}.*[d]{4}:[d]{2}:[d]{2}:[d]{2}])/ ){ print "$line matched: $1n"; } UPDATE2 你做错了一些事情. 我没有看到你将东西存储到日期哈希中. print "nn $line matched : $_n"; 应该看起来像你看到的哈希,这没有多大意义.你想用这个存储的日期数据做什么? $data{$1} = "some value,which is up to you"; 你不能在一个for循环中循环遍历两个哈希. for my $foo (keys %h)(keys %h2) { # do stuff } 对于最后一个排序位,您应该只对键进行排序 for my $key (sort keys %seen ) { (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |