使用Unix排序对多个键进行排序

Chr*_*anz 131 unix linux sorting

我有可能需要按1-n键排序的大文件.其中一些键可能是数字键,其中一些可能不是.这是一个固定宽度的柱状文件,因此没有分隔符.

使用Unix排序有一个很好的方法吗?使用一个键就像使用'-n'一样简单.我已阅读该手册页并简要搜索了Google,但没有找到一个好的例子.我将如何实现这一目标?

注意:由于文件大小的可能性,我已经排除了Perl.这将是最后的手段.

and*_*ras 302

请注意:

如果要主要按字段3对文件进行排序,其次按字段2排序,则不需要:

sort -k 3 -k 2 < inputfile
Run Code Online (Sandbox Code Playgroud)

你想要这个:

sort -k 3,3 -k 2,2 < inputfile
Run Code Online (Sandbox Code Playgroud)

第一个按字符串从字段3的开头到行尾(可能是唯一的)对文件进行排序.

-k, --key=POS1[,POS2]     start a key at POS1 (origin 1), end it at POS2
                          (default end of line)
Run Code Online (Sandbox Code Playgroud)

  • 改变生活.谢谢. (7认同)
  • @Arun POS 在手册页的末尾进行了解释。您只需将排序选项附加到字段编号,如下所示:`sort -k 3,3nr -k 2,2` (3认同)
  • 啊。多么违反直觉的界面:`-k2` 应该是`-k2,2`,尾随逗号`-k2,` 应该是'神奇的默认行尾或其他什么'。 (3认同)
  • 哎呦!现在我必须修复一个脚本,因为早些时候我只看到了上面的第一个答案...好东西我还没有依赖脚本输出.... (2认同)
  • 我的天。手册页作者赢得了记录这一点最没有帮助的方式的竞赛。我已经阅读了 28 年的 Unix 手册页。他们没有提到 -k 字段可以重复。 (2认同)

Cli*_*rce 93

-k选项是你想要的.

-k 1.4,1.5n -k 1.14,1.15n
Run Code Online (Sandbox Code Playgroud)

将在第一个字段中使用字符位置4-5(它是固定宽度的所有字段)并在数字上排序为第一个键.

第二个键也是第一个字段中的字符14-15.

(编辑)

示例(我只有DOS/cygwin方便):

dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r
Run Code Online (Sandbox Code Playgroud)

对于数据:

12/10/2008  01:10 PM         1,564,990 outfile.txt
Run Code Online (Sandbox Code Playgroud)

按月编号(位置4-5)对目录列表进行数字排序,然后按文件名(位置40-60)反向排序.由于没有标签,因此所有字段1都要排序.

  • 有关如何使用选项(数字、反向)的示例非常有用,因为几乎不可能仅从手册页中找到如何使用选项,而且其他答案也没有提及。我希望我能为此+2。;) (2认同)

Ken*_*tle 69

使用-k选项(或--key=POS1[,POS2]).它可以出现多次,每个键都可以有全局选项(例如n用于数字排序)

  • 如果你不想疯狂,也可以看看andras的答案. (46认同)
  • 从排序手册页:"POS是F [.C] [OPTS],其中F是字段编号,C是字段中的字符位置;两者都是原点1." 有关完整文档,请参见手册页. (7认同)

edW*_*edW 21

这里是一个用csv文件按数字和字典顺序排序各列,第5列和后面的字典顺序

~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d  sort.csv
1,10,b,22,Ga
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C

~/test>cat sort.csv
2,3,a,9,C
2,2,b,20,F
2,2,c,19,Gb,hj
2,2,c,19,Gb,hi
2,2,c,19,Ga
2,2,b,22,Ga
1,10,b,22,Ga
Run Code Online (Sandbox Code Playgroud)

注意-k1,1n表示从第1列开始到第1列结束的数字.如果我在下面完成,它将连接第1列和第2列,使1,10排序为110

~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d  sort.csv
2,2,b,20,F
2,2,b,22,Ga
2,2,c,19,Ga
2,2,c,19,Gb,hi
2,2,c,19,Gb,hj
2,3,a,9,C
1,10,b,22,Ga
Run Code Online (Sandbox Code Playgroud)

  • 这是最好的答案,因为它显示了如何为不同的列使用不同的开关 (3认同)

Don*_*oon 12

我相信你的情况就像

sort -t@ -k1.1,1.4 -k1.5,1.7 ... <inputfile
Run Code Online (Sandbox Code Playgroud)

会更好.@是字段分隔符,确保它是一个无处出现的字符.然后您的输入被视为由一列组成.

编辑:显然clintp已经给出了类似的答案,抱歉.正如他所指出的,标志'n'和'r'可以添加到每个-k ....选项中.


ron*_*ron 5

注意,也可能需要使用-s开关来稳定排序,以便同等排序的线也在输出中保持其原始相对顺序.