做它在单次通过:
#! /usr/bin/perl
use warnings;
use strict;
# for demo only
*ARGV = *DATA;
my %msg;
while (<>) {
if (s!^.*postfix/\w+\[.+?\]: (\w+):\s*!!) {
my $key = $1;
push @{ $msg{$key}{$1} } => $2
while /\b(to|from|client)=(.+?)(?:,|$)/g;
}
}
use Data::Dumper;
$Data::Dumper::Indent = 1;
print Dumper \%msg;
__DATA__
Apr 8 14:22:02 MailSecure03 postfix/smtpd[32388]: BA1CE38965: client=mail.example.com[x.x.x.x]
Apr 8 14:22:03 MailSecure03 postfix/cleanup[32070]: BA1CE38965: message-id=<[email protected]>
Apr 8 14:22:03 MailSecure03 postfix/qmgr[19685]: BA1CE38965: from=<[email protected]>, size=1087, nrcpt=2 (queue active)
Apr 8 14:22:04 MailSecure03 postfix/smtp[32608]: BA1CE38965: to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10025, delay=1.7, delays=1/0/0/0.68, dsn=2.0.0, status=sent (250 OK, sent 49DC509B_360_15637_162D8438973)
Apr 8 14:22:04 MailSecure03 postfix/smtp[32608]: BA1CE38965: to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10025, delay=1.7, delays=1/0/0/0.68, dsn=2.0.0, status=sent (250 OK, sent 49DC509B_360_15637_162D8438973)
Apr 8 14:22:04 MailSecure03 postfix/qmgr[19685]: BA1CE38965: removed
Apr 8 14:22:04 MailSecure03 postfix/smtpd[32589]: 62D8438973: client=localhost.localdomain[127.0.0.1]
Apr 8 14:22:04 MailSecure03 postfix/cleanup[32080]: 62D8438973: message-id=<[email protected]>
Apr 8 14:22:04 MailSecure03 postfix/qmgr[19685]: 62D8438973: from=<[email protected]>, size=1636, nrcpt=2 (queue active)
Apr 8 14:22:04 MailSecure03 postfix/smtp[32417]: 62D8438973: to=<[email protected]>, relay=y.y.y.y[y.y.y.y]:25, delay=0.19, delays=0.04/0/0.04/0.1, dsn=2.6.0, status=sent (250 2.6.0 <[email protected]om> Queued mail for delivery)
Apr 8 14:22:04 MailSecure03 postfix/smtp[32417]: 62D8438973: to=<[email protected]>, relay=y.y.y.y[y.y.y.y]:25, delay=0.19, delays=0.04/0/0.04/0.1, dsn=2.6.0, status=sent (250 2.6.0 <[email protected]> Queued mail for delivery)
Apr 8 14:22:04 MailSecure03 postfix/qmgr[19685]: 62D8438973: removed
代码工作由第一寻找一个队列ID(例如,BA1CE38965
和62D8438973
以上),这是我们在$key
存储。
接下来,我们找到当前行上的所有匹配(感谢/g
开关),看起来像to=<...>
,client=mail.example.com
等等 - 带和不带分隔逗号。
在图案
值得注意的是
\b
- 匹配to
或from
或client
(.+?)
- - 该字段的值与相匹配的字边界只(防止匹配xxxto=<...>
)
(to|from|client)
上匹配非贪婪的量词
(?:,|$)
- 匹配逗号或字符串结尾从捕获到$3
非贪婪(.+?)
迫使比赛停止在它遇到,而不是最后的第一个逗号。否则,在一条线上
to=<[email protected]>, other=123
你会得到<[email protected]>, other=123
作为收件人!
然后对于匹配的每个字段,我们push
它将其放到数组的末尾(因为可能有多个收件人)连接到队列ID和字段名称。看看结果:
$VAR1 = {
'62D8438973' => {
'client' => [
'localhost.localdomain[127.0.0.1]'
],
'to' => [
'<[email protected]>',
'<[email protected]>'
],
'from' => [
'<[email protected]>'
]
},
'BA1CE38965' => {
'client' => [
'mail.example.com[x.x.x.x]'
],
'to' => [
'<[email protected]>',
'<[email protected]>'
],
'from' => [
'<[email protected]>'
]
}
};
现在说要打印所有的消息,其队列ID是BA1CE38965
收件人:
my $queueid = "BA1CE38965";
foreach my $recip (@{ $msg{$queueid}{to} }) {
print $recip, "\n":
}
也许你只想知道有多少收件人:
print scalar @{ $msg{$queueid}{to} }, "\n";
如果你愿意承担每个消息都只有一个客户端,与
012访问
在我看来,哈希可能是一个更好的方式来处理这个问题?这样,您不必在迭代时明确检查匹配。您可以简单地使用“to =”行作为关键。 – 2010-02-03 19:38:02