基本理念是这样的。假设您要使用awk从管道中搜索多个模式的文件:
... | awk -f - '{...}' someFile.txt
*'...'只是一些代码的简称 *' - f - '表示模式取自管道
有没有办法知道在awk脚本中每个时刻搜索哪个模式
(就像你知道$ 1是第一个字段,是否有像$ PATTERN一样包含当前模式
搜索或找到类似的东西?
更多详细说明:
如果我有2个文件:
someFile.txt包含:
1
2
4
patterns.txt包含:
1
2
3
4
运行此命令:
cat patterns.txt |awk -f - '{...}' someFile.txt
我应该在大括号之间键入什么,以便只有patterns.txt中的模式 someFile.txt中没有匹配打印?(在这种情况下,patterns.txt中的数字3不匹配)
答案 0 :(得分:1)
根据patterns.txt
作为标准输入提供的要求以及使用awk
进行处理的要求:
$ cat patterns.txt | awk 'FNR==NR{p=p "\n" $0;next;} p !~ $0' someFile.txt -
3
使用GNU awk
进行了测试。
我们想从patterns.txt中删除与someFile.txt中的一行匹配的任何内容。为此,我们首先阅读someFile.txt并从中创建模式。接下来,我们只打印patterns.txt中与someFile.txt中的任何模式都不匹配的行。
FNR==NR{p=p "\n" $0;next;}
NR
是awk
到目前为止读取的行数,FNR
是awk
到目前为止从当前文件读取的行数。因此,如果FNR==NR
,我们仍在阅读第一个命名文件:someFile.txt
。我们将所有这些行保存在换行符分隔的变量p
中。然后我们告诉awk
跳过剩余的命令并跳转到next
行。
p !~ $0
如果我们到了这里,那么我们现在在命令行上读取第二个命名文件,该文件是stdin的-
。此布尔条件的计算结果为true或false。如果是,则打印该行。如果没有,则跳过它。换句话说,上面是awk的隐藏速记:
p !~ $0 {print $0}
答案 1 :(得分:0)
cmd | awk 'NR==FNR{pats[$0]; next} {for (p in pats) if ($0 ~ p) delete pats[p]} END{ for (p in pats) print p }' - someFile.txt
答案 2 :(得分:0)
awk中的另一种方式
cat patterns.txt | awk 'NR>FNR&&!($0 in a);{a[$0]}' someFile.txt -