在Linux shell中排序&uniq

yas*_*sin 50 linux sorting shell uniq

以下命令有什么区别?

sort -u FILE

sort FILE | uniq
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 81

使用sort -u比I/O少sort | uniq,但最终结果是相同的.特别是,如果文件足够大,sort必须创建中间文件,那么sort -u使用稍微更少或略小的中间文件是一个不错的机会,因为它可以消除重复,因为它正在排序每个集合.如果数据高度重复,这可能是有益的; 如果事实上几乎没有重复,它将没有太大的区别(绝对是二阶性能效果,与管道的第一阶效果相比).

请注意,有时候管道是合适的.例如:

sort FILE | uniq -c | sort -n
Run Code Online (Sandbox Code Playgroud)

这会将文件按文件中每行出现次数的顺序排序,最重复的行最后出现.(我发现这种组合,对于Unix或POSIX来说是惯用的,可以用GNU排序压缩成一个复杂的'sort'命令,这并不奇怪.)

有时不使用管道很重要.例如:

sort -u -o FILE FILE
Run Code Online (Sandbox Code Playgroud)

这将文件"原位"排序; 也就是说,输出文件由指定-o FILE,并且此操作保证安全(在覆盖输出之前读取文件).


P S*_*ved 10

有一点不同:返回代码.

问题是,除非shopt -o pipefail设置了管道命令的返回码,否则将返回最后一个的返回码.并且uniq总是返回零(成功).尝试检查退出代码,你会看到类似这样的东西(pipefail这里没有设置):

pavel@lonely ~ $ sort -u file_that_doesnt_exist ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
2
pavel@lonely ~ $ sort file_that_doesnt_exist | uniq ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
0
Run Code Online (Sandbox Code Playgroud)

除此之外,命令是等效的.


wil*_*dye 8

谨防!虽然"sort -u"和"sort | uniq"是等价的,但排序的任何其他选项都可以打破等价.以下是coreutils手册中的一个示例:

例如,'sort -n -u'在检查唯一性时仅检查初始数字字符串的值,而'sort -n | uniq'检查整条生产线.

同样,如果对关键字段进行排序,则sort使用的唯一性测试不一定会查看整行.在被过去的那个bug咬了之后,这些天我倾向于在编写Bash脚本时使用"sort | uniq".我宁愿拥有更高的I/O开销,而不是冒着商店里的其他人在修改我的代码以添加额外的排序参数时不会知道这个特定陷阱的风险.


kni*_*ttl 6

sort -u 将稍快,因为它不需要在两个命令之间管道输出

还看到我关于这个主题的问题:调用uniq并在shell中以不同的顺序排序