Sort
按十六進制值排序
使用 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