Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Tweaking the mysteries of HoHs and arrays

by billie_t (Sexton)
on Nov 19, 2007 at 09:05 UTC ( [id://651620]=perlquestion: print w/replies, xml ) Need Help??

billie_t has asked for the wisdom of the Perl Monks concerning the following question:

This is following up on a previous question (at 620459) that McDarren gave me a lot of assistance with. I'm hoping to do a minor tweak of that same script. It's parsing Postfix logs to display data relating to specific mail transactions. It will nicely give me any info related to a given queue ID that is required. However, one item - the message recipient - may have more than one parameter. I've come up with some code shown below that will help if there is only one other recipient, but if there is more than that, it makes sense to "push" any other entries into an array (and eventually join them into a scalar with delimiters to print out) - this is the part I'm having trouble addressing.
Here's the code I have, which will deal with one or two recipients:
if ($line =~ /relay=127\.0\.0\.1/) { my ($id, $to, $status) = (split /\s+/, $line, 10)[5,6,9]; chop($id); $to =~ s/to=<(.*?)>,/$1/; if ( defined $messages{$id}{to} ) { $messages{$id}{to2} = $to; } else { $messages{$id}{to} = $to; } } for my $id (%messages) { no warnings 'uninitialized'; $messages{$id}{from} =~ /\@(\w+\..+)/; print "$messages{$id}{date}\t$id\t$messages{$id}{from}\t$messages{ +$id}{to}"; if (defined $messages{$id}{to2} ) { print ", $messages{$id}{t +o2}"; } print "\n"; }
The output should be as follows:
Nov 16 10:28:51 66AE820809D Terry.Puser@ourdomain.com carols@th +eirdomain.com.au, daleb@theirdomain.com.au[, ...]
So, the part where I'm futzing around with $messages{$id}{to2} is really where I should be shoving any extra values into an array, I think. I've still not got my head around using references as in this script, so pointers to the appropriate syntax would be appreciated. Since the majority of messages only have one recipient, I'm happy to keep $messages{$id}{to} for those instances. A snippet of mail log with a message with two recipients is below:
Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: connect from mailserver.ou +rdomain.gov.au[168.x.x.x] Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: 66AE820809D: client=mailse +rver.ourdomain.gov.au[[168.x.x.x] Nov 16 10:28:51 smtp3 postfix/cleanup[19600]: 66AE820809D: message-id= +<56FE9AD99802CE47AF144E03064331D501F42840@mailserver.gov.au> Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 66AE820809D: from=<Terry.Pus +er@ourdomain.com>, size=11466, nrcpt=2 (queue active) Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: connect from localhost.loc +aldomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: disconnect from mailserver +.ourdomain.gov.au[168.132.65.6] Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: 883822080A4: client=localh +ost.localdomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/cleanup[19594]: 883822080A4: message-id= +<56FE9AD99802CE47AF144E03064331D501F42840@mailserver.ourdomain.gov.au +> Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 883822080A4: from=<Terry.Pus +er@ourdomain.com>, size=11644, nrcpt=2 (queue active) Nov 16 10:28:51 smtp3 postfix/smtp[18745]: 66AE820809D: to=<carols@the +irdomain.com.au>, relay=127.0.0.1[127.0.0.1], delay=0, status=sent (2 +50 Ok: queued as 883822080A4) Nov 16 10:28:51 smtp3 postfix/smtp[18745]: 66AE820809D: to=<daleb@thei +rdomain.com.au>, relay=127.0.0.1[127.0.0.1], delay=0, status=sent (25 +0 Ok: queued as 883822080A4) Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: disconnect from localhost. +localdomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 66AE820809D: removed Nov 16 10:28:52 smtp3 postfix/smtp[19429]: 883822080A4: to=<carols@the +irdomain.com.au>, relay=mailhost.theirdomain.com.au[203.x.x.x], delay +=1, status=sent (250 Message queued) Nov 16 10:28:52 smtp3 postfix/smtp[19429]: 883822080A4: to=<daleb@thei +rdomain.com.au>, relay=mailhost.theirdomain.com.au[203.x.x.x], delay= +1, status=sent (250 Message queued) Nov 16 10:28:52 smtp3 postfix/qmgr[9315]: 883822080A4: removed

Replies are listed 'Best First'.
Re: Tweaking the mysteries of HoHs and arrays
by McDarren (Abbot) on Nov 19, 2007 at 10:43 UTC
    Howdy :)

    What you need to do is replace these lines:

    if ( defined $messages{$id}{to} ) { $messages{$id}{to2} = $to; } else { $messages{$id}{to} = $to; }
    With this:
    push @{$messages{$id}{to}}, $to;
    This will give you a HOHOA, and will cater for as many recipients as are found.
    Run the following sample code to get an idea.
    #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my %messages; while (my $line = <DATA>) { if ($line =~ /relay=127\.0\.0\.1/) { my ($id, $to, $status) = (split /\s+/, $line, 10)[5,6,9]; chop($id); $to =~ s/to=<(.*?)>,/$1/; push @{$messages{$id}{to}}, $to; } } print Dumper(\%messages) and exit; __DATA__ Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: connect from mailserver.ou +rdomain.gov.au[168.x.x.x] Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: 66AE820809D: client=mailse +rver.ourdomain.gov.au[[168.x.x.x] Nov 16 10:28:51 smtp3 postfix/cleanup[19600]: 66AE820809D: message-id= +<56FE9AD99802CE47AF144E03064331D501F42840@mailserver.gov.au> Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 66AE820809D: from=<Terry.Pus +er@ourdomain.com>, size=11466, nrcpt=2 (queue active) Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: connect from localhost.loc +aldomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/smtpd[17709]: disconnect from mailserver +.ourdomain.gov.au[168.132.65.6] Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: 883822080A4: client=localh +ost.localdomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/cleanup[19594]: 883822080A4: message-id= +<56FE9AD99802CE47AF144E03064331D501F42840@mailserver.ourdomain.gov.au +> Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 883822080A4: from=<Terry.Pus +er@ourdomain.com>, size=11644, nrcpt=2 (queue active) Nov 16 10:28:51 smtp3 postfix/smtp[18745]: 66AE820809D: to=<carols@the +irdomain.com.au>, relay=127.0.0.1[127.0.0.1], delay=0, status=sent (2 +50 Ok: queued as 883822080A4) Nov 16 10:28:51 smtp3 postfix/smtp[18745]: 66AE820809D: to=<daleb@thei +rdomain.com.au>, relay=127.0.0.1[127.0.0.1], delay=0, status=sent (25 +0 Ok: queued as 883822080A4) Nov 16 10:28:51 smtp3 postfix/smtpd[19599]: disconnect from localhost. +localdomain[127.0.0.1] Nov 16 10:28:51 smtp3 postfix/qmgr[9315]: 66AE820809D: removed Nov 16 10:28:52 smtp3 postfix/smtp[19429]: 883822080A4: to=<carols@the +irdomain.com.au>, relay=mailhost.theirdomain.com.au[203.x.x.x], delay +=1, status=sent (250 Message queued) Nov 16 10:28:52 smtp3 postfix/smtp[19429]: 883822080A4: to=<daleb@thei +rdomain.com.au>, relay=mailhost.theirdomain.com.au[203.x.x.x], delay= +1, status=sent (250 Message queued) Nov 16 10:28:52 smtp3 postfix/qmgr[9315]: 883822080A4: removed

    Hope this helps,
    Darren :)

      Hello again!

      Thank you - I didn't get my brackets in the right place when I tried variations along those lines. Or the array symbol outside the brackets. D'oh!

      Thank you again: it's working perfectly. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://651620]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-24 21:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found