Sort by hex value

coreutilssort

Using coreutils sort, how can I sort numerically by a hexadecimal value (field)? I was expecting something along the lines of

sort -k3,3x file_to_sort

however, such an x does not exist.

Edit: Best solution I came up with so far is:

{ echo ibase=16; cut -d' ' -f3 file_to_sort; } |
  bc | paste -d: - file_to_sort | sort -t: -k1,1n | cut -d: -f2-

where the cut -d' ' -f3 isolates the search field (this is -k3,3 — this may vary, of course), and bc does conversion to decimal (requires upper-case hex, without 0x prefix, matching my case). Then I join, sort, and split columns.

Minimal sample input:

5 hhf 25
3 ezh ae
1 hdh d12
2 ukr 9f
4 jjk 7

Expected output (file sorted by hex third column):

4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12

Best Answer

A solution in 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

Explanation

  • While processing file, we create an array of array @h, each of its element is an array reference [$F[-1],$_], with first element is the hex value to compare, and the second element is the whole line.

  • In END block, we use Schwartzian transform:

    • With each element of @h, create an anonymous array, contains the whole line ( $_->[1] the second element of each array ref in @h ) and the hex value to compare hex($_->[0])]

    • Sort above array base on the hex value $a->[1] <=> $b->[1]

    • Get the first element of each array ref in sorted array map { $_->[0] } then print the result.

Update

With @Joseph R's suggestion, without using Schwartzian Transform:

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

Update 2

After reading stefan's comment, I think this can call 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
Related Question