2

我有两个带有两个单列表的文件:

//file1 - 唯一值的完整列表
AAA
BBB
CCC

//file2
AAA
AAA
BBB
BBB

//所以这里的结果是:
CCC

我需要从 file1 中生成一个在 file2 中没有匹配项的值列表。我必须使用 bash 脚本(最好没有 awk 等特殊工具)或 DOS 批处理文件。

谢谢你。

4

3 回答 3

4

方法一

看起来像是grep-v 标志的工作。

grep -v -F -f  listtocheck uniques

方法二

Drake Clarris 的解决方案的一个变体(可以扩展到使用多个文件进行检查,grep除非它们首先合并,否则无法做到),将是:

(
    sort < file_to_check | uniq
    cat reference_file reference_file
) | sort | uniq -u

通过这样做,in 中的任何单词都file_to_check将出现在由括号中的子shell 组合的输出中,仅出现一次。单词 inreference_file至少输出两次,并且出现在两个文件中的单词将至少输出 3 次——一个来自第一个文件,两次来自第二个文件的两个副本。

只剩下找到一种方法来隔离我们想要的单词,那些出现一次的单词,这就是sort | uniq -u它的作用。

优化一

如果reference_file包含很多重复项,则可能值得运行更重的

sort < reference_file | uniq
sort < reference_file | uniq

取而代之的是cat reference_file reference_file,为了有更小的输出和更轻的最终重量sort

优化二

如果我们使用临时文件,这会更快,因为合并已经排序的文件可以有效地完成(并且在重复检查不同文件的情况下,我们可以一次又一次地重复使用相同的排序参考文件,而无需重新排序它); 所以

sort < file_to_check  | uniq > .tmp.1
sort < reference_file | uniq > .tmp.2
# "--merge" works way faster, provided we're sure the input files are sorted
sort --merge .tmp.1 .tmp.2 .tmp.2 | uniq -u
rm -f .tmp.1 .tmp.2

优化三

最后,如果在一个文件中运行很长时间的相同行,例如某些日志记录系统可能就是这种情况,运行两次可能也是值得的uniq,一次摆脱运行(ahem),另一次使其唯一化,因为在线性时间中工作,而线性uniq时间。sort

uniq < file | sort | uniq > .tmp.1
于 2012-08-14T15:32:18.277 回答
2

对于 Windows CMD 解决方案(通常称为 DOS,但实际上并非如此):

它应该像这样简单

findstr /vlxg:"file2" "file1"

但是有一个findstr 错误,当有多个文字搜索字符串时,可能会丢失匹配项。

如果可以接受不区分大小写的搜索,则添加该/I选项可以绕过该错误。

findstr /vlixg:"file2" "file1"

如果您不限于本机 Windows 命令,则可以下载适用于 Windows 的 grep 等实用程序。用于 Windows 的 Gnu 实用程序是一个很好的来源。然后你可以在 Windows 和 'nix 上使用 Isemi 的解决方案。

为 Windows 编写 VBScript 或 JScript 解决方案也很容易。

于 2012-08-14T16:02:22.327 回答
1
cat file1 file2 | sort | uniq -u
于 2012-08-14T16:03:25.253 回答