【发布时间】:2014-04-09 02:13:12
【问题描述】:
我有一系列文件,想知道哪些文件符合特定标准(例如,$1 == "ice" && $2 == "cream")。在同一个文件中多次满足此标准。当满足此条件时,我希望 awk 打印一次文件名。
我希望我说清楚了。
【问题讨论】:
标签: if-statement awk criteria
我有一系列文件,想知道哪些文件符合特定标准(例如,$1 == "ice" && $2 == "cream")。在同一个文件中多次满足此标准。当满足此条件时,我希望 awk 打印一次文件名。
我希望我说清楚了。
【问题讨论】:
标签: if-statement awk criteria
试试这个(下一个文件是 GNU 扩展):
awk '$1=="ice" && $2=="cream"{print FILENAME;nextfile}' file1 file2 file3
或者如果你没有 GNU:
awk 'FNR==1{p=0} $1=="ice" && $2=="cream" && !p {print FILENAME;p=1}' file1 file2 file3
FNR==1 在每个文件的开头重置p 标志,然后当满足您的条件时,p 标志设置为1,因此文件名只出现一次。
顺便说一句,你可能更喜欢这样的简单性:
grep -l "^ice.*cream" file*
它不完全相同,但非常相似。
接受后编辑
这是另一种可能更优雅的可能性。它将匹配文件的名称保存在数组names[] 中,并在末尾打印数组names[] 的键。
awk '$1=="ice" && $2=="cream" {names[FILENAME]++} END{for(i in names)print i}'
【讨论】:
exit 这里会这样做,它只会打印找到的第一个文件名。如果他喜欢所有带有ice 和cream 的文件,它将失败。在 grep 中使用正则表达式,如果行在 ice 之前有 cream 将失败
END 部分的第二个版本仅在命中位于多个文件中时才打印最后一个文件。
my cold ice cream
awk 应该这样做
awk '$1 == "ice" && $2 == "cream" {print FILENAME}' *
要获取行号和行信息,您可以使用:
awk '$1 == "ice" && $2 == "cream" {print NR,$0,"->",FILENAME}' *
另一个版本:
awk '/^ice cream/ {print NR,$0,"->",FILENAME}' *
【讨论】: