Por que o awk executa ambas as ações?

5

Quando eu executo o comando:

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

O arquivo é:

May 19 04:44:43 server postfix/smtpd[32595]: CDAB515013: client=servidor.dominio.com.br[10.10.10.44]
May 19 04:44:43 server postfix/cleanup[18651]: CDAB515013: message-id=<[email protected]>
May 19 04:44:43 server postfix/qmgr[16684]: CDAB515013: [email protected], size=19590, nrcpt=1 (queue active)
May 19 04:44:50 server postfix/pipe[32596]: CDAB515013: [email protected], 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

A saída é:

[email protected],
[email protected],
[email protected],

O problema é que a linha "[email protected]" ocorre duas vezes! Como posso consertar isso?

Versão do AWK: GNU Awk 4.0.0
SO: Debian 6, OpenSuse 12.1, CentOS 6.2

    
por Gilles 20.09.2012 / 16:45

2 respostas

7

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

O motivo é:

[email protected],
              ^^
              ^^
    
por 20.09.2012 / 16:50
3

Todas as ações são executadas em ordem, se a entrada corresponder ao padrão correspondente. Se a entrada corresponder aos dois padrões, ambas as ações serão executadas.

Se você deseja imprimir o campo se ele corresponde a um padrão ou outro, combine os dois:

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

Aqui você pode combinar as duas expressões em uma única correspondência de expressão regular:

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

Para o que você está fazendo, você deve ancorar a correspondência no início do campo, já que provavelmente não deseja corresponder aos endereços de e-mail que contêm a substring from ou to :

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

Se você deseja um tratamento diferente, com essa correspondência mais precisa, é possível usar ações separadas, pois esses padrões não se sobrepõem.

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

Se você quiser parar de processar outras ações e passar para a próxima linha, use a palavra-chave next .

    
por 21.09.2012 / 02:23

Tags