When I run the command:

awk '/from/ {print $7} /to/ { print $7}' erroMuitoDoido.txt

The file is:

May 19 04:44:43 server postfix/smtpd[32595]: CDAB515013: client=servidor.dominio.com.br[]
May 19 04:44:43 server postfix/cleanup[18651]: CDAB515013: message-id=<20120519074443.CDAB515013@servidor2.dominio.com.br>
May 19 04:44:43 server postfix/qmgr[16684]: CDAB515013: from=atendimento@dominio.com.br, size=19590, nrcpt=1 (queue active)
May 19 04:44:50 server postfix/pipe[32596]: CDAB515013: to=userdestino@dominiodestino.com.br, relay=dovecot, delay=6.2, delays=0.02/6/0/0.14, dsn=2.0.0, status=sent (delivered via dovecot service)
May 19 04:44:50 server postfix/qmgr[16684]: CDAB515013: removed

The output is:


The problem is that the line "from=atendimento@dominio.com.br," occurs twice! How can I fix this?

AWK version: GNU Awk 4.0.0
OS: Debian 6, OpenSuse 12.1, CentOS 6.2

migrated from serverfault.com Sep 20 '12 at 14:53

This question came from our site for system and network administrators.

$ awk '/from=/ {print $7} /to=/ { print $7}' erroMuitoDoido.txt

The reason is:

  • 2
    Even simpler: /from=/ || /to=/ { print $7 } – jw013 Sep 20 '12 at 14:56
  • If someone has from= or to= in their e-mail address, you'll have the same problem. Unlikely, but you might as well make it : from= and : to= to make false positives even less likely. – Jim Paris Sep 20 '12 at 20:05

All actions are executed in order if the input matches the corresponding pattern. If the input matches both patterns, both actions are executed.

If you want to print the field whether it matches one pattern or the other, combine the two:

awk '/from/ || /to/ { print $7}' erroMuitoDoido.txt

Here you can combine the two expressions into a single regexp match:

awk '/from|to/ { print $7}' erroMuitoDoido.txt

For what you're doing, you should anchor the match at the beginning of the field, as you probably don't want to match email addresses that happen to contain the substring from or to:

awk '$7 ~ /^(from|to)=/ { print $7}' erroMuitoDoido.txt

If you want different treatment, with this more precise matching, you can use separate actions since these patterns don't overlap.

awk '$7 ~ /^from=/ { … } $7 ~ /^to=/ { … }' erroMuitoDoido.txt

If you want to stop processing further actions and move on to the next line, you can use the next keyword.

  • You wrote “anchor the match at the beginning of the field”, but still match against $0. You probably intended to write $7~/^(from|to)=/. As I am not sure that will always be the $7, maybe / (from|to)=/ would be better. – manatwork Sep 21 '12 at 9:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy