“ Ungrep”-哪些模式不匹配


13

我正在寻找执行以下命令的命令或脚本:

file1.txt:

abcd
efgh 
ijkl
mnop

file2.txt:

123abcd123
123efgh123
123mnop123

我想要一个执行以下操作的命令:

ungrep file1.txt file2.txt

并返回以下内容:

ijkl

换句话说,它给了我file1.txt中的行,该行不会在file2.txt的grep上返回任何结果。我知道我可以通过以下方式来做到这一点:遍历file1.txt,为每行grepping file2.txt并存储结果,并输出结果为空的任何行,但是我希望找到一种更有效的方法。

Answers:


18

使用GNU grep,以下方法应该起作用。使用该-f选项,将其file1.txt作为“模式文件”传递-还将第二次作为数据文件传递。用于-o仅报告匹配的零件。最后,提取仅匹配一次的单词-这些单词对应于在中file1.txt找不到匹配项的行file2.txt

grep -h -o -f  file1.txt file2.txt file1.txt | sort | uniq -u
ijkl

非常好的描述。谢谢,+ 1。
unxnut

4
您可以在没有grep技巧的情况下达到相同的效果:sort file1.txt <(grep -of file1.txt file2.txt) | uniq -u但是,像您的解决方案一样,这仅在模式文件实际上不包含任何正则表达式元字符的情况下才有效。
rici

@rici,这是一个很好的观点
iruvar

2
改进:grep -oFf file1.txt file2.txt | sort file1.txt - | uniq -u
斯特凡Chazelas

10

你可以这样来做awk

awk '
  NR == FNR {w[$0]; next}
  {for (i in w) if (index($0,i)) delete w[i]}
  END {for (i in w) print i}' file1.txt file2.txt

通过使用index,我们正在寻找子字符串,而不是匹配正则表达式。

因为我们在找到匹配项后立即从数组中删除了单词,所以避免了不必要的搜索。


1
我只会接受这一点。它不会调用任何O(n log n)排序,并且当模式包含正则表达式元字符时不会奇怪地失败,并且可以扩展为支持正则表达式。
卡兹(Kaz)2013年

我简直不敢相信,简单地求值w[$0]就有将键添加到数组的副作用。
卡兹(Kaz)2013年

1
@Kaz,是的,这可能会造成混淆,并且您发现许多脚本不是故意if (a[$1])而不是if ($1 in a)例如通过故意分配数组元素来执行的。awk包括原始版本awk和的情况都是如此nawk,但是昨天查看标准时,我找不到指定的标准。
斯特凡Chazelas

1
@Kaz这是POSIX的引文:“应用程序应确保将与in运算符一起使用的多维索引括括号内。in 运算符测试特定数组元素的存在,不应导致该元素存在。对不存在的数组元素的其他引用将自动创建它。” 此处向上滚动一个或两个段落可以找到它。
jw013

1
只要file1不是很大(对于巨大的某种价值),我file2就更喜欢这种解决方案,因为它不需要任何排序,而且效率会更高。
jw013
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.