有没有办法获得在AWK脚本中搜索的当前模式?

时间:2014-10-19 20:21:25

标签: regex awk sh gawk

基本理念是这样的。假设您要使用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不匹配)

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;}

    NRawk到目前为止读取的行数,FNRawk到目前为止从当前文件读取的行数。因此,如果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 -