2010-11-17 69 views
2

昨天我在这里问了一个关于onelinermjschultz的问题,给了我一个答案,我立即爱上了:) Awk刚刚销毁了手头的任务,解析了一个大日志文件(500+ MB)在几秒钟内。现在我试图将我的其他线索移植到awk上。awk从maillog解析唯一IP地址

这是一个问题:

grep "pop3\[" maillog | grep "User logged in" | 
egrep -o '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}' | sort -u 

我需要使用POP3所有唯一的IP地址列表连接到邮件服务器。

这是一个示例日志条目:

Nov 15 00:49:21 hostname pop3[19418]: login: [10.10.10.10] username plaintext 
User logged in 

所以我找到含有“POP3”的所有线条和我分析他们部分“登录的用户”。接下来,我使用egrep和一个正则表达式来匹配IP地址,我使用排序来过滤出重复地址。

这是我到目前为止有我的awk的版本:

awk '/pop3\[.*.User logged in/ {ip[$7]=0} END {for (address in ip) 
{ print address} }' maillog 

这完美的作品,但因为始终不是所有的日志条目是相同的,例如有时IP被移动到了8场喜欢这里:

Nov 15 10:42:40 hostname pop3[2232]: login: hostname.domain.com [20.20.20.20] 
username plaintext User logged in 

用awk捕捉这些条目的最佳方法是什么?

一如既往感谢事先所有伟大的回应,你教我这么多已经:)

回答

3

AWK代码

只是符合您的IP格式...要小心,没有其他格式...

/pop3\[.*.User logged in/ { 
     where = match($0,/\[[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) 
     if (where) 
      ip[substr($0,RSTART+1,RLENGTH-1)]=0 
} 

END {for (address in ip) 
{ print address} } 

运行在ideone

+0

完美的代码!正是我所需要的,并且感谢ideone,直到现在,从来没有见过该网站,这正在我的书签工具栏尽快。 – f10bit 2010-11-17 00:55:57

0

这看起来更像是Perl的领土比awk中对我说:

my %ip_addresses =(); 
while (<>) 
{ 
    next unless m/pop3\[/; 
    next unless m/User logged in/; 
    if (my($ip) = $_ =~ m/(\d{1,3} (?: [.] \d{1,3}){3})/msx) 
    { 
     $ip_addresses{$ip} = 1; 
    } 
} 
foreach my $ip (sort keys %ip_addresses) 
{ 
    print "$ip\n"; 
} 

的排序是不完美 - 是字母而不是数字(因此192.1.168.10将出现在9.25.13.26之前)。当然,这可以是固定的。

0

看到和尝试这些后方法我有一个新的想法。

belisarius的代码做我要求的,但因为它必须做所有的正则表达式匹配它不是最快的,速度是我所追求的。

所以我想出了这个,因为你可以看到“有问题”的日志行有一个额外的字段,使他们都长13个字段,而不是正常的12,所以我只删除额外的领域,这给了我IP地址的正确的列表,然后我用awk再次删除所有重复的条目:

awk '/pop3\[.*.User logged in/ {{if (NF == 13) $7="";gsub(FS "+",FS)};print $7}' 
/var/log/maillog | awk '!($0 in a){a[$0];print}' 

Ideone link,如果你想在行动中看到