我会保持简单并使用默认字段分隔符——然后使用 sub 或 split 清理每个字段以进行打印。这是拆分解决方案。
awk '{ split($3, uid, "="); split($5, exe, "/"); print uid[2], exe[3] }'
这是如何开发的:
$ echo 'xyz msg=(1448783938.658:149777): uid=505 comm="abc.py" exe="/install/python/bin' | awk '{ print $3, $5 }'
uid=505 exe="/install/python/bin
$ echo 'xyz msg=(1448783938.658:149777): uid=505 comm="abc.py" exe="/install/python/bin' | awk '{ split($3, uid, "="); print uid[2], $5 }'
505 exe="/install/python/bin
$ echo 'xyz msg=(1448783938.658:149777): uid=505 comm="abc.py" exe="/install/python/bin' | awk '{ split($3, uid, "="); split($5, exe, "/"); print uid[2], exe[3] }'
505 python
我首先尝试了一个基于 sub 的解决方案,但结果证明它比基于 split 的解决方案更长更神秘——split em> 解决方案似乎更简单。 (在需要基于 sub 的解决方案的情况下,也许 sed 会是更好的候选语言。)
应该添加一些过滤器,以确保我们只处理有效行,它可以像下面这样简单:
awk '$3 ~ /uid=/ && $5 ~ /exe="\/install\// { split($3, uid, "="); split($5, exe, "/"); print uid[2], exe[3] }'
另一件事...如果 uid 和 exe 字段在您的文件中逐列移动,您将不得不使用 for 循环来寻找它们...以下:
#! /usr/bin/awk -f
{
u=0
e=0
for (i=1; i<=NF; i++) {
if ($i ~ /uid=/)
u=i
else if ($i ~ /exe="\/install\//)
e=i
if (u && e)
break
}
if (!u || !e)
next
split($u, uid,"=")
split($e, exe, "/")
print uid[2], exe[3]
}
在这种情况下,我们在前面的示例中放入的用于检查有效性的主要模式嵌入在 for 循环中。