我有一个文本文件,例如 sitelist1.txt(文件 A),其中包含一些 URL,如下所示:
http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
http://orkut.com/archived
我有另一个文本文件,例如 sitelist2.txt(文件 B),其中包含许多现有 URL。
我试过:
fgrep -v -f sitelist1.txt sitelist2.txt
问题是 - 这还会显示 sitelist2.txt 中存在而不是 sitelist1.txt 中存在的 URL
答案1
您传递的内容-v
使其执行与您预期相反的操作 - 它向您显示,对于 中的每一行sitelist1.txt
,其中的所有行sitelist2.txt
都不匹配。所以我敢打赌,你会看到很多重复的内容。您想使用不带选项的相同命令-v
:
fgrep -f sitelist1.txt sitelist2.txt
这将执行以下英语指令:对于 中的每一行sitelist1.txt
,显示sitelist2.txt
包含我感兴趣的文件 1 行的所有行,作为整行或作为文件 2 行的一部分。
该-v
选项是“反向匹配”选项,它显示所有不匹配的行。
答案2
约翰的回答(除了问题下的评论中指出的误解之外)是问题的答案,但是我还想指出,对于像这样的简单操作combine
(更多实用程序)是一个不错的选择;它非常容易使用,因为它允许使用布尔运算符(支持 AND、OR、NOT 和 XOR)来表达要完成的操作:
combine sitelist1.txt NOT sitelist2.txt
% cat sitelist1.txt
http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
http://orkut.com/archived
% cat sitelist2.txt
http://www.facebook.com
http://www.twitter.com
http://myspace.com/profile
% combine sitelist1.txt NOT sitelist2.txt
http://orkut.com/archived
与大多数实用程序相反,输入文件不需要进行排序(尽管我猜它们仍然在内部排序),但是在使用时fgrep
存在一个陷阱,如果重复行sitelist1.txt
不想被打印。如果sitelist1.txt
包含重复行并且您不想打印它们,则必须将combine
的输出通过管道传输到sort -u
:
combine sitelist1.txt NOT sitelist2.txt | sort -u
答案3
如果您正在寻找每行中的完整网址而不是子字符串,您可以使用comm
comm -23 <(sort -u fileA) <(sort -u fileB)
说明:
comm 需要排序输入,因此我们首先对 2 个文件进行排序和唯一化(sort -u file)
。
接下来 - 使用进程替换将 的输出sort -u
作为“文件”传递给 comm,因为 comm 需要 files: comm <() <()
。
最后 - 抑制第 2 列(文件 B 特有的行)和第 3 列(两个文件共有的行)以仅输出第 1 列中的行(文件 A 特有的行)。