Sort

按十六進制值排序

  • July 5, 2020

使用 coreutils sort,如何按十六進制值(欄位)進行數字排序?我期待著類似的東西

sort -k3,3x file_to_sort

但是,這種x情況並不存在。

編輯:到目前為止我想出的最佳解決方案是:

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

其中cut -d' ' -f3隔離搜尋欄位(這是-k3,3- 當然這可能會有所不同),並bc轉換為十進制(需要大寫十六進制,沒有0x前綴,匹配我的情況)。然後我加入、排序和拆分列。

最小樣本輸入:

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

預期輸出(文件按hex第三列排序):

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

中的解決方案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

解釋

  • 在處理文件時,我們創建了一個數組數組@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

更新 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

我使用這個範例數據:

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

這個想法是使用十進制形式的排序欄位創建此數據的新版本。即awk轉換它,將其添加到每一行,對結果進行排序,最後一步刪除添加的欄位:

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

這導致此輸出:

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

引用自:https://unix.stackexchange.com/questions/139801