我要为exim4 MTA编写日志解析器,我有几个问题。 (我知道有一个exilog计划)
问题: 1.什么是更好的解析方法? (它的abbout 5Gb这样的线:D) 我有这个$ line:
的 2011-12-24 12:32:12 MeSSag3-Id-Ye <hostname> (from@some.email) <to@some.email> => H=[321.123.321.123] T="Hello this is a test"
的
并希望将所有字段变为变量。
我现在正在使用likethat ($var,[var2])=($line =~ /somecoolregexp/ )
;它是快/好还是我应该用别的东西?
答案 0 :(得分:1)
嗯,这取决于您想要对数据做什么。
假设你有一个很大的while (<>) { ... }
,你可以通过使用split来获得最简单的解析:
my @fields = split;
下一级将添加一些含义
my ($date, $time, $id, $host, $from, $to, undef, $dest) = split;
(注意,如果要忽略结果,可以指定给undef
)
最后,你可以使用正则表达式来清理很多错误。您还可以将上面的拆分与较小的正则表达式相结合,以单独清理每个字段。
my ($datetime, $id, $host, $from, $to, $dest) =
/([\d-]+ [\d:]+) \s+ # date and time together
(\S+) \s+ # message id, just a block of non-whitespace
<(.*?)> \s+ # hostname in angle brackets, .*? is non-greedy slurp
\((.*?)\) \s+ # from email in parens
<(.*?)> \s+ # to email in angle brackets
\S+ \s+ # separated between to-email and dest
(\S+) # last bit, could be improved to (\w)=\[(.*?)\]
/x; # /x lets us break all of this up, so its a bit readable
当然,你可以继续把它带到各种各样的愚蠢,但如果你要开始对这些字段进行更具体的解析,我会先进行初始拆分,然后再进行分解字段解析。例如:
my ($date, $time, ...) = split;
my ($year, $month, $day) = split(/-/, $date);
my ($hour, $min, $sec) = split(/:/, $time);
my ($from_user, $from_host) = ( $from =~ /< ([^\@]+) \@ (.*) >/x );
...etc...