我到处看到有人需要获取经过排序的唯一列表,他们总是通过管道发送给sort | uniq。我从未见过有人使用sort -u代替的任何示例。为什么不?有什么区别,为什么使用uniq优于唯一标志进行排序?

评论

aplawrence.com/Unixart/sort-vs-uniq.html

#1 楼

sort | uniqsort -u之前存在,并且与更广泛的系统兼容,尽管几乎所有现代系统都支持-u-它是POSIX。这主要是追溯到不存在sort -u的日子(如果人们知道自己的工作方式仍然继续,人们就不会改变其方法,只需看看ifconfigip的采用情况即可)。 />这两个很可能合并了,因为删除文件中的重复项需要排序(至少在标准情况下),这是排序的一种非常常见的用例。由于能够同时执行两个操作(并且由于在uniqsort之间不需要IPC的事实),它在内部也更快。尤其是如果文件很大,sort -u可能会使用更少的中间文件来对数据进行排序。
它也不会掩盖sort的返回码,这可能很重要(在现代shell中,有很多方法可以做到这一点,例如,bash$PIPESTATUS数组,但这并不总是正确的。) br />

评论


我倾向于使用排序| uniq,因为10中有9次,实际上是在管道连接uniq -c。

– lu头
13年5月16日在14:16

请注意,sort -u是大约在1979年的第七版UNIX的一部分。不支持-u的sort版本确实是过时的,或者是在未关注POSIX法律标准之前的实际标准的情况下编写的。另请参阅从2010开始在Linux Shell中进行Stack Overflow Sort&uniq。

–乔纳森·莱弗勒(Jonathan Leffler)
15年2月18日在16:34

由于ip +1。现在是2016年,2013年是这篇文章,但现在我只了解ip命令。

–死
16年5月27日在2:22

+1表示“ 9出10,实际上我正在管道传递给uniq -c”(也许还可以通过管道传递对-nr | head进行排序)。我想知道什么是sort |当我发现Vim具有:sort u命令时,在Vim中使用uniq。 TIL排序-u也存在。

–魏卓云
17-10-13在7:09

注意,使用sort -n |时有所不同。 uniq与排序-n -u。例如,尾部和前导空格将被按-n -u排序视为重复项,而不被前者视为! echo -e'测试\ n测试'| sort -n -u返回测试,但是回显-e'test \ n test'|排序-n | uniq返回两行。

– mxmlnkn
18年1月10日在23:05

#2 楼

一个区别是uniq具有许多有用的附加选项,例如跳过用于比较的字段并计算值的重复次数。 sort-u标志仅实现未经修饰的uniq命令的功能。

评论


+0.49是有用的答案,但我会这样说:“不能将sort -u的输出传递给uniq来使用后者的一些有用选项,例如跳过用于比较的字段和计算重复次数。 ”

–l0b0
13年5月16日在14:10

+1以抵消反对者的反对,因为“没有办法直接从排序中做到这一点”确实回答了这个问题……

–伊兹卡塔
13年5月16日在15:28

#3 楼

使用POSIX兼容的sortuniq(目前不兼容GNU uniq),存在一个差异,即sort使用语言环境的整理算法比较字符串(通常将使用strcoll()比较字符串),而uniq检查字节值身份(通常使用strcmp())¹。
至少有两个原因很重要。 。例如,在GNU系统上的en_US.UTF-8语言环境中,所有①②③④⑤⑥⑦⑧⑨⑩...字符²和许多其他字符都按相同的顺序进行排序,因为它们的排序顺序未定义。 0123456789阿拉伯数字的排序方式与它们的东阿拉伯印度字母对应的字符(٠١٢٣٤٥٦٧٨٩)相同。使用sort -u的GNU sort -uuniq除外),①与②不同以及0123与different不同,因此uniq会考虑所有4个唯一。字符(当输入的字节序列不构成有效字符时,行为未按POSIX定义),而strcoll()则不关心字符,因为它仅进行字节对字节的比较。因此,这就是为什么-i如果其中某些行没有形成有效的文本,可能不会为您提供所有唯一行的原因。 uniq,尽管仍未在非文本输入中指定,但实际上更可能因该原因而为您提供独特的行。到目前为止,strcoll的词法是对整行进行比较,而strcmp()sort -u是根据命令行中给出的排序规范进行比较。
¹先前版本的POSIX规范引起混乱,但是将sort|uniq变量列为影响uniq的变量,该变量已在2018年版中删除,并且在上述讨论之后明确了行为。请参阅相应的Austin组错误
²2019编辑。自那以后,这些问题已得到修复,但是从GNU libc 2.30版开始,仍有超过95%的Unicode代码点具有未定义的顺序。您可以使用test进行测试,例如在较新的版本中进行测试

#4 楼

我更喜欢使用sort | uniq,因为当我尝试使用-u(消除重复项)选项来删除涉及大小写混合的字符串的重复项时,要理解结果并不容易。

注意:在运行之前在下面的示例中,您需要通过执行以下操作来模拟标准C整理顺序:

LC_ALL=C
export LC_ALL


例如,如果我要对文件进行排序并删除重复项,而同时,保持不同的字符串大小写不同。

$ cat short      #file to sort
Pear
Pear
apple
pear
Apple

$ sort short     #normal sort (in normal C collating sequence)
Apple            #the lower case words are at the end
Pear
Pear
apple
pear

$ sort -f short  #correctly sorts ignoring the C collating order
Apple            #but duplicates are still there
apple
Pear
Pear
pear

$ sort -fu short #By adding the -u option to remove duplicates it is 
apple            #difficult to ascertain the logic that sort uses to remove
Pear             #duplicates(i.e., why did it remove pear instead of Pear?)


通过不使用-u选项删除重复项,可以解决此混淆。使用uniq更可预测。下面首先对大小写进行排序并忽略该大小写,然后将其传递给uniq以删除重复项。

$ sort -f short | uniq
Apple
apple
Pear
pear


评论


-u sort选项输出等号运行的第一个(请参见手册页)。因此,sort -fu选择了每个不区分大小写的唯一行的第一次出现。排序用于删除重复项的逻辑是可以预测的。

– pallxk
2015年10月9日15:33

#5 楼

我今天发现的另一个区别是,基于定界符进行排序时,sort -u仅将唯一标志应用于您进行排序的列。

评论


这是StéphaneChazelas的回答中提到的,但我喜欢您的例子,所以+1

–roaima
17年1月6日在9:16



感谢您指出@roaima,答案不太清楚

– Stefanos Chrs
17年1月6日,9:19