做它在單次通過:
#! /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