当前位置: 首页 > 科技观察

在命令行使用sort排序

时间:2023-03-15 23:39:21 科技观察

在Linux、BSD或Mac的终端中使用sort命令根据您的需要重新排列数据。如果您曾经使用过电子表格应用程序,您就会知道您可以按列的内容对行进行排序。例如,如果您有一个费用清单,您可能希望按日期或价格升序对它们进行排序,或者按类别对它们进行排序。如果熟悉终端的使用,就不会为了整理文本数据而使用庞大的办公软件。这正是sort命令的用途。您不必安装sort,因为它一直包含在POSIX系统中。在大多数Linux系统上,sort命令来自GNU组织打包的实用程序集合。在其他POSIX系统上,如BSD和Mac,GNU不提供默认的排序命令,因此某些选项可能不同。在本文中,我尝试描述GNU和BSD实现。AlphabetizeLines默认情况下,sort命令读取文件中每一行的第一个字符,并按字母升序对每一行进行排序以便输出。如果两行中的第一个字符相同,则比较下一个字符。例如:$catdistro.listSlackwareFedoraRedHatEnterpriseLinuxUbuntuArch1337MintMageiaDebian$sortdistro.list1337ArchDebianFedoraMageiaMintRedHatEnterpriseLinuxSlackwareUbuntu使用排序不会更改原始文件。sort只起到过滤器的作用,所以如果要以排序后的格式保存数据,需要使用>或tee进行重定向。$排序发行版列表|teedistro.sorted1337ArchDebian[...]$catdistro.sorted1337ArchDebian[...]按列对复杂数据集进行排序有时需要对不止每行的第一个字符进行排序。例如,假设您有一个动物列表,每个动物都有其物种和属,每个“字段”(即数据表中的“单元格”)都有一个可预测的分隔符。这种从数据表导出的格式很常见,CSV(comma-separateddatacomma-separatedvalues)后缀可以识别这些文件(虽然CSV文件不一定用逗号分隔,分隔文件不一定使用CSV后缀)。以下数据作为示例:Aptenodytes;forsteri;Miller,JF;1778;EmperorPygoscelis;papua;Wagler;1832;GentooEudyptula;minor;Bonaparte;1867;LittleBlueSpheniscus;demersus;Brisson;1760;AfricanMegadyptes;antipodes;Milne-Edwards;1880年;Yellow-eyedEudyptes;chrysocome;Viello;1816;SouthernRockhopperTorvaldis;linux;Ewing,L;1996;Tux对于这组示例数据,您可以使用--field-separator(-t在BSD和Mac上,也在GNU上使用abbreviation-t)将分隔符设置为分号(由于示例数据使用分号而不是逗号,分隔符理论上可以是任何字符),使用--key(在BSD和Mac上使用-k,在GNU中也可以使用简写-k)选项指定对哪个字段进行排序。例如,要对每行的第二个字段进行排序(计数从1而不是0开始):sort--field-separator=";"--key=2Megadyptes;antipodes;Milne-Edwards;1880;Yellow-eyedEudyptes;chrysocome;Viellot;1816;SothernRockhopperSpheniscus;demersus;Brisson;1760;AfricanAptenodytes;forsteri;Miller,JF;1778;EmperorTorvaldis;linux;Ewing,L;1996;TuxEudyptula;minor;Bonaparte;1867;LittleBluePygoscelis;lerpapua;183W;;Gentoo的结果有点难读,但Unix以其管道命令的方式而闻名,因此您可以使用column命令来美化输出。使用GNU列:$sort--field-separator=";"\\--key=2penguins.list|column--table--separator";"MegadyptesantipodesMilne-Edwards1880Yellow-eyedEudypteschrysocomeViellot1816SouthernRockhopperSpheniscusdemersusBrisson1760AfricanAptenodytesforsteriMiller,JF1778EmperorTorvaldislinuxEwing,L1996TuxEudyptulaminorBonaparte1867Genoputogissortingpa1y对于初学者来说可能有点迷惑(但好写),BSD命令和Mac上的排序选项-t";"\-k2企鹅.list|column-t-s";"MegadyptesantipodesMilne-Edwards1880Yellow-eyedEudypteschrysocomeViellot1816SouthernRockhopperSpheniscusdemersusBrisson1760AfricanAptenodytesforsteriMiller,JF1778EmperorTorvaldislinuxEwing,L1996TuxEudyptulaminorBonaparte1867LittleBluePygosk不必设置为2。任何现有字段都可以设置为排序键。倒序您可以使用--reverse(BSD/Mac上的-r,或GNU上的短-r)选项来倒转已经排序的列表。$sort--reversealphabet.listzyxw[...]您还可以将输出通过管道传递给命令tac以达到相同的效果。按月排序(仅限GNU)理想情况下,每个人都根据ISO8601标准编写日期:年、月、日。这是指定计算机也可以轻松理解的精确日期的合乎逻辑的方法。在许多情况下,人类以其他方式标记日期,包括使用非常随意的名称的月份。幸运的是,GNUsort命令可以识别这种表示法并按月份名称正确排序。使用--month-sort(-M)选项:$catmonth.listNovemberOctoberSeptemberApril[...]$sort--month-sortmonth.listJanuaryFebruaryMarchAprilMay[...]NovemberDecember可以识别完整月份和缩写月份。人类可读的数字排序(仅由GNU支持)人类和计算机之间另一个常见的混淆点是数字的组合。例如,人类通常将“1024KB”写成“1KB”,因为人类解析“1KB”比“1024”更容易和更快(数字越大,差异越明显)。对于计算机来说,9KB的字符串大于1MB(尽管9KB是1MB的很小一部分)。GNUsort命令提供了--human-numeric-sort(-h)选项来帮助正确解析这些值。$catsizes.list2M12MB1k9k9007000$sort--human-numeric-sort90070001k9k2M12MB有一些例外。例如,“16000字节”大于“1KB”,但排序无法识别。$catsizes0.list2M12MB160001k$sort-hsizes0.list160001k2M12MB从逻辑上讲,这个例子中的16000应该写成16KB,所以不能全怪罪于GNUsort。--human-numeric-sort可以以计算机友好的方式解析为人类可读的数字,只要您确保数字的一致性。随机排序(仅GNU支持)有时工具也会提供一些不是为它设计的选项。在某种程度上,sort命令提供随机排序文件的能力是没有意义的。此命令的工作流程使此功能变得方便。您可以使用另一个命令,如shuf,或者您可以向当前命令添加一个选项。无论您认为它是臃肿的还是创造性的UX设计,GNUsort命令都提供了随机排序文件的能力。最纯粹的随机排序格式选项是--random-sort或-R(不要与-r混淆,后者是--reverse的简写)。$sort--random-sortalphabet.listdmpa[...]对文件运行随机排序每次都会有不同的结果。结束语GNU和BSD排序命令的功能要多得多,因此请花点时间了解这些选项。您会惊讶于排序的灵活性,尤其是与其他Unix工具一起使用时。