【问题标题】:Sort & uniq in Linux shellLinux shell 中的排序和唯一性
【发布时间】:2010-08-01 17:07:26
【问题描述】:

下面的to命令有什么区别?

sort -u FILE

sort FILE | uniq

【问题讨论】:

  • 当你运行它们时,你看到了什么?您是否尝试为不同大小的文件收集时间差异?您可以进行一些实验并将结果发布为您问题的一部分。
  • 我想知道是否有特殊情况是两个命令的行为不同,在正常执行中它们都给出相同的结果
  • @mtk:关于 U&L 的 Q&A 本质上是重复的,但在这个问题多年后被问到。答案中的历史评论很有趣。 -u 选项在 UNIX 第 7 版 sort(大约 1979 年)中,所以提到的古代历史确实很古老。
  • @Jonathan 好吧,我发布它的原因与历史评论很有趣的原因相同 :) 另外它还说明了一些计时实验。

标签: linux shell sorting uniq


【解决方案1】:

使用sort -usort | uniq 执行更少的I/O,但最终结果是相同的。特别是,如果文件足够大以至于sort 必须创建中间文件,那么sort -u 很有可能会使用稍少或稍小的中间文件,因为它可以在对每个集合进行排序时消除重复项。如果数据高度重复,这可能是有益的;如果实际上重复的很少,它不会有太大的区别(绝对是二阶性能效果,与管道的一阶效果相比)。

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

sort FILE | uniq -c | sort -n

这会将文件按文件中每行出现次数的顺序排序,重复次数最多的行出现在最后。 (如果发现这种 Unix 或 POSIX 惯用的组合可以用 GNU sort 压缩成一个复杂的“排序”命令,我不会感到惊讶。)

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

sort -u -o FILE FILE

这会“原位”对文件进行排序;即输出文件由-o FILE指定,保证此操作安全(文件在被覆盖之前被读取输出)。

【讨论】:

  • 感谢您的完整回答!
  • gnu sort 没有办法完成所有sort | uniq -c | sort -n,我也没有找到任何其他工具来有效地完成它。编写代码似乎是一件值得的事情。
【解决方案2】:

有一点不同:返回码。

问题是,除非设置了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

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

【讨论】:

    【解决方案3】:

    小心!虽然“sort -u”和“sort|uniq”确实是等价的,但任何额外的排序选项都可能破坏等价性。这是 coreutils 手册中的一个示例:

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

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

    【讨论】:

      【解决方案4】:

      sort -u 会稍微快一些,因为它不需要在两个命令之间传递输出

      另请参阅我关于该主题的问题:calling uniq and sort in different orders in shell

      【讨论】:

        【解决方案5】:

        我曾在一些排序不支持'-u'选项的服务器上工作过。那里我们必须使用

        sort xyz | uniq
        

        【讨论】:

        • 您是否愿意大致指定哪些服务器使用哪个操作系统版本以及何时?第 7 版 UNIX™ sort 支持 -u,这是第一个广泛使用的 UNIX 版本,因此所有其他版本(System III、System V、BSD 等)都倾向于遵循它,所以我确实会感到惊讶找到sort 不支持-u 的类Unix 系统。
        【解决方案6】:

        没有,它们会产生相同的结果

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-16
          • 2011-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-24
          • 1970-01-01
          • 2012-09-14
          相关资源
          最近更新 更多