uniq 显示重复行

uniq 显示重复行
$ grep home american.txt | sort | uniq                                                                                            
A home and a country should leave us no more!                                                                                        
Between their loved home and the war's desolation!                                                                                 
O'er the land of the free and the home of the brave!                                                                                  
O'er the land of the free and the home of the brave!                                                                                  
O'er the land of the free and the home of the brave?     

为什么显示两条重复的行?

这是输出grep home american.txt | cat -A

O'er the land of the free and the home of the brave?^M$
O'er the land of the free and the home of the brave!^M$
A home and a country should leave us no more! ^M$
O'er the land of the free and the home of the brave!^M$
Between their loved home and the war's desolation!^M$
O'er the land of the free and the home of the brave!$

答案1

O'er自由的土地和勇敢的家园!

上面这一行出现了 3 次。前两次出现的末尾都有回车符。第三次出现则不然。您可以使用以下命令来可视化它:

猫-A american.txt

这是由于该文本文件末尾缺少空行造成的。
我认为在 Unix/Linux 世界中,文本文件末尾始终有一个空行是一种约定。

我在测试时发现其他一些有趣的事情:

  • 该命令在 cygwin 中的工作方式有所不同。
  • grep home american.txt | sort| uniq -u工作得很好。

答案2

正如怀疑的那样戴大卫CAS这两行实际上是不同的,但唯一的区别在于看不见的字符。

您的文件是 Windows 文本文件。在 Windows 文本文件中,行由两个字符序列 CR、LF(回车、换行)分隔。在 Unix 文本文件中,行以 LF(换行符,也称为换行符)字符终止。cat -A显示一个 CR^M和一个换行符,$后跟一个换行符。

当 Unix 实用程序处理 Windows 文本文件时,Unix 实用程序会在每行末尾看到一个额外的 CR 字符。对于 Unix 实用程序而言,CR 只是一个普通字符;末尾带有 CR 的行与除了末尾缺少 CR 之外其他相同的行不同。此外,在Windows上,换行符序列是分隔符,因此文件末尾没有CR、LF。但在 Unix 上,文本文件总是以 LF 字符结尾,除非它是空的。因此,当您使用 Unix 实用程序处理 Windows 文本文件时,Unix 实用程序看到的是每行末尾带有 CR 的文件(因为 CR 字符不是换行符的 Unix 编码的一部分),以及一些尾随文本这不是一行的一部分(因为末尾缺少换行符)。

由于缺少最终换行符,Unix 文本实用程序在输入不是有效文本文件时执行的操作有所不同。 GNU 实用程序(您可以在非嵌入式 Linux 和 Cygwin 上找到)努力将此类文件视为文本文件并保留最终换行符的缺失。该sort命令会随机排列行,虽然它确实处理未完成的输入行,但它总是在输出末尾发出换行符。因此,对于该sort命令来说,您所拥有的内容看起来像是一堆行,每一行都以字符 CR 结尾,除了最后一个输入行不以 CR 结尾。在输出中,除了与最后一个输入行相对应的一行之外,所有行均以 CR 结尾。

uniq看到一堆以brave!和 CR 结尾的行,并且只保留其中的一个。它还会看到以 CR 结尾但没有 CR 的一行brave!,它会尽职尽责地发出 CR,因为该行与其他每一行都不同。

当您在终端上打印输出时,CR 字符指示终端将光标移动到当前行的开头; LF 字符指示终端将光标移动到下一行的开头。因此,序列 LF 和 CR,LF 在视觉上无法区分,并且您会看到两条看起来相同的线。该命令cat -A添加可打印字符以使其与众不同。

答案3

其中以 结尾的行brave!有回车符 ( ^M),另一行则没有。uniq是的,他们是不同的。

文件中除最后一行外的所有行都有回车符。它之所以有它们,是因为它是由 MS-DOS 或 Windows 文本编辑器创建的(使用 CR/LF 作为行结束符,而不是 unixish 的仅 LF 或 \n)。文件中的最后一行没有 CR 或 LF (否则下面会有一个空行)。

这就是为什么,例如,如果您tail -1 american.txt在文本所在的同一行看到下一个 shell 提示符,且没有换行符。

相关内容