Answers:
sort | uniq
以前存在sort -u
,并且与更广泛的系统兼容,尽管几乎所有现代系统都支持-u
POSIX。这主要是回溯到sort -u
不存在的时代(如果人们知道的方式继续起作用,人们就不会改变他们的方法,只看ifconfig
vs. ip
采用)。
可能合并了这两者,因为删除文件中的重复项需要排序(至少在标准情况下),这是排序的一种非常常见的用例。由于能够同时执行两个操作(并且由于它在uniq
和之间不需要IPC的事实),因此在内部也更快sort
。特别是如果文件很大,sort -u
将可能使用较少的中间文件来对数据进行排序。
在我的系统上,我始终得到如下结果:
$ dd if=/dev/urandom of=/dev/shm/file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 8.95208 s, 11.7 MB/s
$ time sort -u /dev/shm/file >/dev/null
real 0m0.500s
user 0m0.767s
sys 0m0.167s
$ time sort /dev/shm/file | uniq >/dev/null
real 0m0.772s
user 0m1.137s
sys 0m0.273s
它也不会掩盖的返回码sort
,这可能很重要(在现代shell中,有多种方法可以获取此值,例如bash
的$PIPESTATUS
数组,但这并不总是正确的)。
sort | uniq
因为实际上是十分之九uniq -c
。
ip
。现在是2016年,这个职位是2013年,但是我ip
现在只了解命令。
uniq -c
”(也可能再次管道连接到sort -nr | head
)。sort | uniq
当我发现Vim有:sort u
命令时,我想知道什么与Vim中的命令等效。TIL也sort -u
存在。
sort -n | uniq
vs.会有所不同sort -n -u
。例如,尾部和前导空格将被sort -n -u
前者视为重复,但前者则不会!echo -e 'test \n test' | sort -n -u
返回test
,但echo -e 'test \n test' | sort -n | uniq
返回两行。
使用POSIX兼容的sort
s和uniq
s(uniq
在这方面,GNU 当前不兼容),区别在于sort
使用语言环境的整理算法比较字符串(通常将strcoll()
用于比较字符串),同时uniq
检查字节值同一性(通常使用strcmp()
) 。
至少有两个原因很重要。
在某些语言环境中,尤其是在GNU系统上,有不同的字符对相同的字符进行排序。例如,在GNU系统上的en_US.UTF-8语言环境中,所有①②③④⑤⑥⑦⑧⑨⑩...字符和许多其他字符都进行了相同的排序,因为它们的排序顺序未定义。0123456789阿拉伯数字的排序与其东部阿拉伯印度字母的对应字符(٠١٢٣٤٥٦٧٨٩)相同。
对于sort -u
,①与②相同,而0123与sort相同,因此sort -u
将仅保留其中的一个,而对于uniq
(不是uniq
使用strcoll()
(除外-i
)的GNU ),①与②不同,并且0123与different不同,因此uniq
将考虑全部4个独特。
strcoll
只能比较有效字符的字符串(当输入包含不构成有效字符的字节序列时,行为未按POSIX定义),strcmp()
而不关心字符,因为它仅进行字节对字节的比较。因此,这是另一个原因,sort -u
如果其中某些行不能形成有效的文本,则可能无法为您提供所有的行。sort|uniq
,尽管仍未在非文本输入中指定,但实际上由于这个原因,您更有可能给您提供独特的提示。除了这些细微差别外,到目前为止尚未注意到的一件事是按uniq
词法比较整行,而sort
的-u
比较则基于命令行中给出的排序规范。
$ printf '%s\n' 'a b' 'a c' | sort -uk 1,1
a b
$ printf '%s\n' 'a b' 'a c' | sort -k 1,1 | uniq
a b
a c
$ printf '%s\n' 0 -0 +0 00 '' | sort -n | uniq
0
-0
+0
00
$ printf '%s\n' 0 -0 +0 00 '' | sort -nu
0
我更喜欢使用,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
,每个不区分大小写的唯一行都将首先出现。sort
用于删除重复项的逻辑是可以预测的。
我今天发现的另一个区别是,当基于分隔符进行排序时,sort -u
仅将唯一标志应用于您进行排序的列。
$ cat input.csv
3,World,1
1,Hello,1
2,Hello,1
$ cat input.csv | sort -t',' -k2 -u
1,Hello,1
3,World,1
$ cat input.csv | sort -t',' -k2 | uniq
1,Hello,1
2,Hello,1
3,World,1