How can I extract all conversations in a Postfix log from a specific client using awk?

I am trying to extract conversations from a Postfix log file based on the client it initiated. This is an awk script that retrieves the identifiers of matching messages:

awk '/client.host.name/ && !(/timeout/||/disconnect/) { sub(":","",$6);print $6}' maillog

This is used to enter the standard Postfix maillog (see sample data below). I think I would like to do this multi-pass file search using the results of the first search, but I'm not sure if this is the right approach. Something like:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid=$6} $0 ~ msgid {print $0}' maillog

But naturally, this does not work properly. I assume that I need to do one of the following:

  • Output the output from the first awk to the second awk or grep (not sure how to use the input stream as a regular expression).
  • Assign the first result set to an array and use the array as a search set. Something like:
    awk '/app02/ && !(/timeout/ || /connect/) { sub(":","",$6);msgid[$6]=$6; } END { for(x in msgid) { print x; } }' maillog
    I'm not sure how I would work in a for loop. Is there a way in awk to β€œrewind” a file and then capture all the lines matching any element of the array?
  • Drop the whole deal and try it with Perl.

So for awk gurus ... is there a way to accomplish what I'm looking for using awk?

Sample data:

Jul 19 05:07:57 relay postfix/smtpd[5462]: C48F6CE83FA: client=client.dom.lcl[1.2.3.4]
Jul 19 05:07:57 relay postfix/cleanup[54]: C48F6CE83FA: message-id=<20100719100757.C48F6CE83FA@relay.dom.lcl>
Jul 19 05:07:57 relay postfix/qmgr[12345]: C48F6CE83FA: from=<root@dom.lcl>, size=69261, nrcpt=6 (queue active)
Jul 19 05:08:04 relay postfix/smtp[54205]: C48F6CE83FA: to=<recip1@example.org>, relay=in.example.org[12.23.34.5]:25, delay=0.7, delays=0.05/0/0.13/0.51, dsn=2.0.0, status=sent (250 ok: Message 200012345 accepted)
Jul 19 05:14:08 relay postfix/qmgr[12345]: C48F6CE83FA: removed`
+3
source share
1 answer

You can use an array. Something like this:

awk '/client.host.name/ && !(/timeout/||/disconnect/) {sub(":","",$6);msgid[$6]=1} {if ($FIELD in msgid) print}' maillog

If you need to substitute the number of the field that contains the data, since I do not know this.

Edit: Moved to the left.

Edit2:

Here is a version specific to your data:

awk '/client.dom.lcl/ && !(/timeout/||/disconnect/) {sub(":","",$6); msgid[$6] = 1} {if (gensub(":", "", 1, $6) in msgid) print}' sampledata

Edit2:

Here's a simplified version:

awk '{id = gensub(":", "", 1, $6)} /client.dom.lcl/ && !(/timeout/||/disconnect/) {msgid[id] = 1} {if (id in msgid) print}' sampledata
+2

Source: https://habr.com/ru/post/1755534/


All Articles