使用Unix sort对带小数部分的正负数进行排序

5

使用 sort (coreutils) 5.2.1

我有一个文件,想按照第4个字段的非整数部分进行排序。这个数可以是负数或正数,也可能是INF。

field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=0.123 field5 field6
field1 field2 field3 tag=4.22 field5 field6
field1 field2 field3 tag=5.77 field5 field6
field1 field2 field3 tag=-1.92 field5 field6
field1 field2 field3 tag=-1.91 field5 field6
field1 field2 field3 tag=INF field5 field6

我希望将此排序为

field1 field2 field3 tag=-1.92 field5 field6
field1 field2 field3 tag=-1.91 field5 field6
field1 field2 field3 tag=0.123 field5 field6
field1 field2 field3 tag=4.22 field5 field6
field1 field2 field3 tag=5.77 field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6

假设字段的数字部分在第4个字符位置(假设索引从0开始,这个我不确定),我尝试使用以下选项对sort进行排序:

  • sort -g -k4.4 inputfile
  • sort -g -k4.5 inputfile
  • sort -n -k4.4 inputfile
  • sort -n -k4.5 inputfile
  • sort -g inputfile

这些都产生了以下结果,接近,但不完全正确。数量大小已正确排序,但我想要最负值排在顶部。

field1 field2 field3 tag=0.123 field5 field6
field1 field2 field3 tag=-1.91 field5 field6
field1 field2 field3 tag=-1.92 field5 field6
field1 field2 field3 tag=4.22 field5 field6
field1 field2 field3 tag=5.77 field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6

我该如何让sort排序函数表现更佳?

顺便提一下,以下是更多信息:

LANG = en_US.UTF-8
Red Hat Enterprise Linux WS release 4 (Nahant Update 6)

我得到了相同的结果。如果去掉 tag= 并且在第一个字段中排序,那么它会按预期排序,但在任何其他带有 tag= 的字段中都不会排序。 - Kevin
2个回答

1
你可以添加一个预处理awk步骤,在末尾添加一个新字段,其中包含来自字段4的数字部分或数字表示,并按此字段排序。添加后处理步骤以剥离该字段。请注意,在下面的示例中,INF已设置为任意高值10**10,如果输入中存在超过此值的自然数,则可以将其设置为更高的值。
awk '{x=$4; sub("tag=", "", x); sub("INF", 10**10, x); print $0, x}' file.txt |
sort -k7,7g | 
cut -f-6 -d' '
field1 field2 field3 tag=-1.92 field5 field6
field1 field2 field3 tag=-1.91 field5 field6
field1 field2 field3 tag=0.123 field5 field6
field1 field2 field3 tag=4.22 field5 field6
field1 field2 field3 tag=5.77 field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6

1
我在Mac上,所以实现可能会有些不同,但我发现这个方法可行:
使用以下命令:sort -gb -k 4.5,4 inputfile 解释:按照数字一般的方式进行排序,在排序时忽略空白,使用第四列数据的第五个元素到该列数据结尾来对inputfile文件进行排序。
field1 field2 field3 tag=-1.92 field5 field6
field1 field2 field3 tag=-1.91 field5 field6
field1 field2 field3 tag=0.123 field5 field6
field1 field2 field3 tag=4.22 field5 field6
field1 field2 field3 tag=5.77 field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6
field1 field2 field3 tag=INF field5 field6

1
确实,sort -gb -k4.5 inputfile 是有效的... 如果删除 -b 选项,则会恢复到我上面展示的错误排序。查看 man sort,可以发现 -b 被列为“忽略前导空格”。我不确定为什么这对我们有帮助,但我喜欢结果。 - tomocafe
另外,您能解释一下“-k4.5,4”的目的是什么吗?据我理解,关键选项意味着从第四个字段的第五个字符开始,并在第四个字段的开头停止。 - tomocafe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接