文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

在命令行用sort进行排序

2024-12-24 21:15

关注

在 Linux、BSD 或 Mac 的终端中使用 sort 命令,按自己的需求重新整理数据。

如果你曾经用过数据表应用程序,你就会知道可以按列的内容对行进行排序。例如,如果你有一个费用列表,你可能希望对它们进行按日期或价格升序抑或按类别进行排序。如果你熟悉终端的使用,你不会仅为了排序文本数据就去使用庞大的办公软件。这正是 sort 命令的用处。

安装

你不必安装 sort ,因为它向来都包含在 POSIX 系统里。在大多数 Linux 系统中,sort 命令来自 GNU 组织打包的实用工具集合中。在其他的 POSIX 系统中,像 BSD 和 Mac,默认的 sort 命令不是 GNU 提供的,所以有一些选项可能不一样。本文中我尽量对 GNU 和 BSD 两者的实现都进行说明。

按字母顺序排列行

sort 命令默认会读取文件每行的第一个字符并对每行按字母升序排序后输出。两行中的第一个字符相同的情况下,对下一个字符进行对比。例如:

  1. $ cat distro.list
  2. Slackware
  3. Fedora
  4. Red Hat Enterprise Linux
  5. Ubuntu
  6. Arch
  7. 1337
  8. Mint
  9. Mageia
  10. Debian
  11. $ sort distro.list
  12. 1337
  13. Arch
  14. Debian
  15. Fedora
  16. Mageia
  17. Mint
  18. Red Hat Enterprise Linux
  19. Slackware
  20. Ubuntu

使用 sort 不会改变原文件。sort 仅起到过滤的作用,所以如果你希望按排序后的格式保存数据,你需要用 >tee 进行重定向。

  1. $ sort distro.list | tee distro.sorted
  2. 1337
  3. Arch
  4. Debian
  5. [...]
  6. $ cat distro.sorted
  7. 1337
  8. Arch
  9. Debian
  10. [...]

按列排序

复杂数据集有时候不止需要对每行的第一个字符进行排序。例如,假设有一个动物列表,每个都有其种和属,用可预见的分隔符分隔每一个“字段”(即数据表中的“单元格”)。这类由数据表导出的格式很常见,CSV(以逗号分隔的数据comma-separated values)后缀可以标识这些文件(虽然 CSV 文件不一定用逗号分隔,有分隔符的文件也不一定用 CSV 后缀)。以下数据作为示例:

  1. Aptenodytes;forsteri;Miller,JF;1778;Emperor
  2. Pygoscelis;papua;Wagler;1832;Gentoo
  3. Eudyptula;minor;Bonaparte;1867;Little Blue
  4. Spheniscus;demersus;Brisson;1760;African
  5. Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
  6. Eudyptes;chrysocome;Viellot;1816;Southern Rockhopper
  7. Torvaldis;linux;Ewing,L;1996;Tux

对于这组示例数据,你可以用 --field-separator (在 BSD 和 Mac 用 -t,在 GNU 上也可以用简写 -t )设置分隔符为分号(因为该示例数据中是用分号而不是逗号,理论上分隔符可以是任意字符),用 --key(在 BSD 和 Mac 上用 -k,在 GNU 上也可以用简写 -k)选项指定哪个字段被排序。例如,对每行第二个字段进行排序(计数以 1 开头而不是 0):

  1. sort --field-separator=";" --key=2
  2. Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyed
  3. Eudyptes;chrysocome;Viellot;1816;Sothern Rockhopper
  4. Spheniscus;demersus;Brisson;1760;African
  5. Aptenodytes;forsteri;Miller,JF;1778;Emperor
  6. Torvaldis;linux;Ewing,L;1996;Tux
  7. Eudyptula;minor;Bonaparte;1867;Little Blue
  8. Pygoscelis;papua;Wagler;1832;Gentoo

结果有点不容易读,但是 Unix 以构造命令的管道方式而闻名,所以你可以使用 column 命令美化输出结果。使用 GNU column

  1. $ sort --field-separator=";" \
  2. \--key=2 penguins.list | column --table --separator ";"
  3. Megadyptes   antipodes   Milne-Edwards  1880  Yellow-eyed
  4. Eudyptes     chrysocome  Viellot        1816  Southern Rockhopper
  5. Spheniscus   demersus    Brisson        1760  African
  6. Aptenodytes  forsteri    Miller,JF      1778  Emperor
  7. Torvaldis    linux       Ewing,L        1996  Tux
  8. Eudyptula    minor       Bonaparte      1867  Little Blue
  9. Pygoscelis   papua       Wagler         1832  Gentoo

对于初学者可能有点不好理解(但是写起来简单),BSD 和 Mac 上的命令选项:

  1. $ sort -t ";" \
  2. -k2 penguins.list | column -t -s ";"
  3. Megadyptes   antipodes   Milne-Edwards  1880  Yellow-eyed
  4. Eudyptes     chrysocome  Viellot        1816  Southern Rockhopper
  5. Spheniscus   demersus    Brisson        1760  African
  6. Aptenodytes  forsteri    Miller,JF      1778  Emperor
  7. Torvaldis    linux       Ewing,L        1996  Tux
  8. Eudyptula    minor       Bonaparte      1867  Little Blue
  9. Pygoscelis   papua       Wagler         1832  Gentoo

当然 -k 不一定非要设为 2。任意存在的字段都可以被设为排序的键。

逆序排列

你可以用 --reverse(BSD/Mac 上用 -r,GNU 上也可以用简写 -r)选项来颠倒已经排好序的列表。

  1. $ sort --reverse alphabet.list
  2. z
  3. y
  4. x
  5. w
  6. [...]

你也可以把输出结果通过管道传给命令 tac 来实现相同的效果。

按月排序(仅 GNU 支持)

理想情况下,所有人都按照 ISO 8601 标准来写日期:年、月、日。这是一种合乎逻辑的指定精确日期的方法,也可以很容易地被计算机理解。也有很多情况下,人类用其他的方式标注日期,包括用很名字随意的月份。

幸运的是,GNU sort 命令能识别这种写法,并可以按月份的名称正确排序。使用 --month-sort-M)选项:

  1. $ cat month.list
  2. November
  3. October
  4. September
  5. April
  6. [...]
  7. $ sort --month-sort month.list
  8. January
  9. February
  10. March
  11. April
  12. May
  13. [...]
  14. November
  15. December

月份的全称和简写都可以被识别。

人类可读的数字排序(仅 GNU 支持)

另一个人类和计算机的常见混淆点是数字的组合。例如,人类通常把 “1024 kilobytes” 写成 “1KB”,因为人类解析 “1 KB” 比 “1024” 要容易且更快(数字越大,这种差异越明显)。对于计算机来说,一个 9 KB 的字符串要比诸如 1 MB 的字符串大(尽管 9 KB 是 1 MB 很小一部分)。GNU sort 命令提供了--human-numeric-sort-h)选项来帮助正确解析这些值。

  1. $ cat sizes.list
  2. 2M
  3. 12MB
  4. 1k
  5. 9k
  6. 900
  7. 7000
  8. $ sort --human-numeric-sort
  9. 900
  10. 7000
  11. 1k
  12. 9k
  13. 2M
  14. 12MB

有一些情况例外。例如,“16000 bytes” 比 “1 KB” 大,但是 sort 识别不了。

  1. $ cat sizes0.list
  2. 2M
  3. 12MB
  4. 16000
  5. 1k
  6. $ sort -h sizes0.list
  7. 16000
  8. 1k
  9. 2M
  10. 12MB

逻辑上来说,这个示例中 16000 应该写成 16 KB,所以也不应该全部归咎于GNU sort。只要你确保数字的一致性,--human-numeric-sort 可以用一种计算机友好的方式解析成人类可读的数字。

随机排序(仅 GNU 支持)

有时候工具也提供了一些与设计初衷相悖的选项。某种程度上说,sort 命令提供对一个文件进行随机排序的能力没有任何意义。这个命令的工作流让这个特性变得很方便。你可以用其他的命令,像 shuf ,或者你可以用现在的命令添加一个选项。不管你认为它是一个臃肿的还是极具创造力的用户体验设计,GNU sort 命令提供了对文件进行随机排序的功能。

最纯粹的随机排序格式选项是 --random-sort-R(不要跟 -r 混淆,-r--reverse 的简写)。

  1. $ sort --random-sort alphabet.list
  2. d
  3. m
  4. p
  5. a
  6. [...]

每次对文件运行随机排序都会有不同的结果。

结语

GNU 和 BSD 的 sort 命令还有很多功能,所以花点时间去了解这些选项。你会惊异于 sort 的灵活性,尤其是当它和其他的 Unix 工具一起使用时。 

 

来源:Linux中国内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯