2016-06-18 38 views
1

解析大文件时,我想解析mail.log文件,以获得两个模式的最后一个出现在同一行,文件解析具有500MB之间的大小& 1 GB性能问题使用awk

我设法用得到它:

$ time awk ' $5~"postfix/error" && $6~"4F0A73A11CF" ' MAIL-POSTFIX-LOG-20160226.log | 
tail -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m3.572s 
user 0m1.920s 
sys  0m1.600s 

我想用awk命令继续,但我需要大幅改善数据解析几天的表现。

通过使用TAC命令扭转文件,从最后一个,我观察到更高的性能与grep命令:

$ time tac MAIL-POSTFIX-LOG-20160226.log | grep "postfix/error" | grep -m1 "4F0A73A11CF" 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m0.026s 
user 0m0.008s 
sys  0m0.016s 

$ time cat MAIL-POSTFIX-LOG-20160226.log | grep "postfix/error" | grep "4F0A73A11CF" | 
tail -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m2.979s 
user 0m0.280s 
sys  0m0.680s 

但试图将TAC和awk命令,性能相结合时,是不是一个预期:

time tac MAIL-POSTFIX-LOG-20160226.log | awk ' $5~"postfix/error" && $6~"4F0A73A11CF" ' | 
head -1 

Feb 26 21:49:23 smtp1 postfix/error[32347]: 4F0A73A11CF: to=<[email protected]>, 
relay=none, delay=88661, delays=88661/0.02/0/0.05, dsn=4.4.1, status=deferred (delivery 
temporarily suspended: connect to xxxxxxxxxxxxxxxxxxxx[x.x.x.x]:25: Connection timed out) 

real 0m19.232s 
user 0m2.840s 
sys  0m4.836s 

任何建议

问候

+0

从查看数据的一行,也许如果包括'['和'制作的假设:'作为字段分隔符,您可以在awk条件中使用'='而不是'〜'(注意字段号也会改变)。 – jas

+0

不知道我理解了关于“[”的评论,我试过了: time tac MAIL-POSTFIX-LOG-20160226.log | awk -F':''$ 3〜“postfix/error”&& $ 4 ==“4F0A73A11CF”'|头-1 真正0m16.003s 用户0m2.756s SYS 0m3.984s 我不得不添加一个空格为第4场的“4F0A73A11CF”,没有大的起色。 – Fdv

+0

是否可以在第一次匹配后停止awk命令,如“grep -m1” 否则使用tac是无用的 – Fdv

回答

0

我认为这个问题是管道头,在第一场比赛后退出时,性能提高:

time tac MAIL-POSTFIX-LOG-20160226.log | awk ' $5~"error" && $6~"4F0A73A11CF" {print; exit} ' 

real 0m0.048s 
user 0m0.024s 
sys  0m0.020s 
+0

没错。你现在正在消除流水线中的任何缓冲问题,并且绝对在第一场比赛中停止awk。另外,请注意,通过在你的正则表达式中使用字符串分隔符('“...”')而不是正则表达式分隔符('/.../'),你迫使awk工作两次,一次将字符串转换为正则表达式然后再次评估正则表达式。使用正则表达式分隔符来分隔正则表达式:'$ 5〜/ error/&& $ 6〜/ 4F0A73A11CF /'。你也可以用一个正则表达式比较而不是2找到一个小的改进:'awk'/ postfix \/error \ [[0-9] + \]:4F0A73A11CF/{print;退出}''。 –

+0

对所有人来说,我没有意识到可以在awk中使用多个分隔符,也不用使用字符串分隔符和正则表达式的影响。 – Fdv