按十六进制值排序

ste*_*fan 16 coreutils sort

使用 coreutils sort,如何按十六进制值(字段)进行数字排序?我期待着类似的东西

sort -k3,3x file_to_sort
Run Code Online (Sandbox Code Playgroud)

然而,这样的x情况并不存在。

编辑:到目前为止我想出的最佳解决方案是:

{ echo ibase=16; cut -d' ' -f3 file_to_sort; } |
  bc | paste -d: - file_to_sort | sort -t: -k1,1n | cut -d: -f2-
Run Code Online (Sandbox Code Playgroud)

其中cut -d' ' -f3隔离搜索字段(这是-k3,3-这可能会有所不同,当然),和bc不转换为十进制(需要大写十六进制,没有0x前缀,匹配我的情况)。然后我加入、排序和拆分列。

最小样本输入:

5 hhf 25
3 ezh ae
1 hdh d12
2 ukr 9f
4 jjk 7
Run Code Online (Sandbox Code Playgroud)

预期输出(按hex第三列排序的文件):

4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Run Code Online (Sandbox Code Playgroud)

Hau*_*ing 6

我使用这个示例数据:

1 hdh d12
2 ukr 9f
3 ezh ae
4 jjk 7
5 hhf 25
Run Code Online (Sandbox Code Playgroud)

这个想法是使用十进制形式的排序字段创建此数据的新版本。即awk转换它,将它添加到每一行,结果被排序,最后一步添加的字段被删除:

awk '{val="0x" $3; sub("^0x0x","0x",val); print strtonum(val),$0 ;}' file | 
  sort -n | 
  sed 's/^[^ ]* //'
Run Code Online (Sandbox Code Playgroud)

这导致此输出:

4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Run Code Online (Sandbox Code Playgroud)


cuo*_*glm 5

解决方案perl

$ perl -anle '
    push @h, [$F[-1],$_];
    END {
        print for map  { $_->[0] }
                  sort { $a->[1] <=> $b->[1] }
                  map  { [$_->[1],hex($_->[0])] } @h;
    }
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Run Code Online (Sandbox Code Playgroud)

解释

  • 在处理文件时,我们创建一个 array 数组@h,它的每个元素都是一个数组引用[$F[-1],$_],第一个元素是要比较的十六进制值,第二个元素是整行。

  • END块中,我们使用Schwartzian 变换

    • 使用 的每个元素@h,创建一个匿名数组,包含整行($_->[1]每个数组 ref in 的第二个元素@h)和要比较的十六进制值hex($_->[0])]

    • 根据十六进制值在数组上方排序 $a->[1] <=> $b->[1]

    • 获取排序数组中每个数组 ref 的第一个元素,map { $_->[0] } 然后打印结果。

更新

根据@Joseph R 的建议,不使用 Schwartzian 变换:

$ perl -anle '
    push @h, [hex($F[-1]),$_];
    END {
        print $_->[1] for
            sort { $a->[0] <=> $b->[0] } @h;
    }
' file
Run Code Online (Sandbox Code Playgroud)

更新 2

阅读 stefan 的评论后,我认为这可以称为direct

$ perl -e '
    print sort {hex((split(/\s+/,$a))[-1]) <=> hex((split(/\s+/,$b))[-1])} <>;
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Run Code Online (Sandbox Code Playgroud)