尝试对两个数字列表进行排序并使用 uniq 来获取交集

尝试对两个数字列表进行排序并使用 uniq 来获取交集

我有一个文件 A 和 B,所以我使用了以下命令......

(sort -n A B) | uniq -d

这应该给我两个文件中出现的数字。

1
2
2
3
4
5
11
11
12
31

这些是我得到的数字,sort -n A B但是当我通过管道传输时,uniq -d我只得到 11 而不是 2。我做错了什么?

答案1

因为用得不多,所以我就提一下基于的解决方案:

comm -12 <(sort A) <(sort B)

这使用进程替换<( ... )对文件 A 和 B 进行排序,并将它们作为输入提供给comm,然后使用-12

  -1     suppress column 1 (lines unique to FILE1) 
  -2     suppress column 2 (lines unique to FILE2)

...只留下两个文件共有的行。

答案2

正如评论所示,问题似乎可能是空格或回车符。以下任一方法都可以解决问题:

$ (sort -n A B) | sed -E 's/[^[:alnum:]]+$//' | uniq -d
$ (sort -n A B) | tr -d '\r ' | uniq -d

某些风格的 GNU sed 使用-r扩展正则表达式来获取。 tr当然更简单,但也更残酷,因为它会删除字符,无论它们是否尾随。

答案3

除了 don_crissti 提到的有关尾随空格的内容之外,您可能还想检查文件类型/换行符样式。 uniq 的手册页指出它可以:

uniq - report or omit repeated lines

如果您说 CRLF 即 Windows 风格的换行符而不是预期的 LF,您可能会感到惊讶。

您可以使用以下方法快速检查类型:

file <filename>

如果你想删除任何 CRLF 结束行序列,你可以通过 dos2unix 运行输入文件。下面将转换结束行字符。

dos2unix A
dos2unix B

答案4

根据文件大小,您可以使用grep

grep -Fxf A B

-f指定从中获取模式列表的文件。

-x表示仅匹配整行(不允许匹配行的一部分)。

-F意味着将模式视为固定字符串而不是正则表达式。

如果B小于,您可以通过命名为模式文件 ( )A来获得稍快的结果。Bgrep -Fxf B A

您可以通过管道输出来sort -u获取每个文件中出现的不同行的排序列表:

grep -Fxf A B | sort -u

当然,如果您的问题是回车行结尾,您应该dos2unix首先使用。

相关内容