为什么 awk 执行这两个操作?

为什么 awk 执行这两个操作?

当我运行命令时:

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

该文件是:

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

输出是:

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

问题是该行“[电子邮件受保护],”出现两次!我该如何解决这个问题?

AWK版本:GNU Awk 4.0.0
操作系统:Debian 6、OpenSuse 12.1、CentOS 6.2

答案1

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

原因是:

[email protected],
              ^^
              ^^

答案2

如果输入与相应的模式匹配,则所有操作将按顺序执行。如果输入与两种模式都匹配,则执行这两个操作。

如果您想打印该字段,无论它与一种模式匹配还是另一种模式匹配,请将两者结合起来:

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

在这里,您可以将两个表达式组合成一个正则表达式匹配:

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

对于您正在做的事情,您应该将匹配锚定在字段的开头,因为您可能不希望匹配恰好包含子字符串from或 的电子邮件地址to

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

如果您想要不同的处理方式,通过这种更精确的匹配,您可以使用单独的操作,因为这些模式不重叠。

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

如果您想停止处理进一步的操作并转到下一行,可以使用关键字next

相关内容