我试图让我的程序通过日志文件进行解析,以尝试找到单词" user"并将其打印到页面,或打印" N / A"如果它找不到它。在我尝试在else语句中编写之前,第一行代码是我的原始示例:
awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i}}}' myFile
除此之外,它的工作原理我现在需要能够设置一个空行或者#N; A&#34;这样我的表中的记录即使特定行没有与之关联的用户也具有适当的值。这是我尝试添加其他案例:
awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i} else {print "stuff"}}}' myFile
它的问题在于它会查看每个字段并打印&#34; N / A&#34;当我只希望它做一次,如果术语&#34;用户&#34;在记录行中找不到。我想过使用NR和NF进行嵌套循环,但是我对这看起来如何看起来很困惑。
样本输入可能是:
status-code=32 action=add user=jim
status-code=43 message=otherException
status-code=32 action=add user=paul
status-code=32 action=delete user=reggie
status-code=2 action=endFile
示例输出看起来像(我有另一段代码修剪&#34; user =&#34;稍后关闭):
user=jim
N/A
user=paul
user=reggie
N/A
在上面的示例中,上面的记录没有为用户提供字段(它们可能是状态消息或错误消息)。我想要包含空行或其他标记,而不是仅仅跳过它们,这样当我执行paste myfile myfile2 > myfile3
命令时,即使不是每列都有用户字段,列也会匹配。
答案 0 :(得分:2)
$ awk '{print (match($0,/user=[^ ]+/) ? substr($0,RSTART,RLENGTH) : "N/A")}' file
user=jim
N/A
user=paul
user=reggie
N/A
答案 1 :(得分:1)
您需要设置一个标志,并且只在标志上打印“N / A”。像这样:
awk '{f=0;for(i=1;i<=NF;i++){if($i~/^user/){print $i;f=1}}if(!f){print "N/A"}}' myFile
顺便说一句,我更喜欢避免不必要的大括号:
awk '{f=0; for (i=1;i<=NF;i++) if ($i~/^user/) {print $i; f=1} if (!f) print "N/A" }' myFile
使用您提供的输入进行测试:
$ cat file
status-code=32 action=add user=jim
status-code=43 message=otherException
status-code=32 action=add user=paul
status-code=32 action=delete user=reggie
status-code=2 action=endFile
$ awk '{f=0; for (i=1;i<=NF;i++) if ($i~/^user/) {print $i; f=1} if (!f) print "N/A" }' file
user=jim
N/A
user=paul
user=reggie
N/A
只是为了好玩,这是使用GNU awk解决问题的另一种方式(基于Ed的有用评论的编辑模式):
$ awk -v FPAT='user=\\S+' '{print NF ? $NF : "N/A"}' file
user=jim
N/A
user=paul
user=reggie
N/A
特殊变量FPAT
用于描述字段的格式。此处,模式匹配“user =”后跟一个或多个非空格字符\S+
(必须转义\
,这就是\\
)的原因。如果没有字段匹配该模式,则NF
为0(即假)并且打印“N / A”。否则,将打印最后一个匹配字段。
当然,如果每条记录可能有多个用户,那么这不起作用,但从您的样本中可以看出只有零或一个。
答案 2 :(得分:1)
如果您碰巧找到与用户匹配的字段,我建议您使用next
语句。
awk '{for(i=1;i<=NF;i++){if($i~/^user/){print $i; next;}} print "N/A";}' myFile