16進値で並べ替え


14

coreutilsを使用sortして、16進値(フィールド)で数値的にソートするにはどうすればよいですか?私はの線に沿って何かを期待していた

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—これはもちろん変化する可能性があります)、bc10進数に変換します(大文字の16進数が必要で、0x接頭辞なしで、私の場合と一致します)。次に、列を結合、並べ替え、分割します。


-k3,3?0xですべて同じ長さの16進数が見られますか?大文字/小文字の混在はありませんか?「はい」の場合、文字列として解釈されたときに適切にソートする必要があります。たぶんあなたは私たちにいくつかのサンプルデータを見せることができますか?

@yeti:残念ながら、ありません。
ステファン

回答:


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

説明

  • ファイルの処理中に、arrayの配列を作成します@h。各要素は配列参照です[$F[-1],$_]。最初の要素は比較する16進値で、2番目の要素は行全体です。

  • ではENDブロック、我々は使用シュワルツ変換します

    • の各要素で@h、匿名配列を作成し、行全体($_->[1]各配列refの2番目の要素@h)と比較する16進値を含みますhex($_->[0])]

    • 16進値に基づいて配列の上に並べ替えます $a->[1] <=> $b->[1]

    • ソートされた配列の各配列refの最初の要素を取得しmap { $_->[0] } 、結果を出力します。

更新

Schwartzian Transformを使用しない@Joseph Rの提案:

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

更新2

ステファンのコメントを読んだ後、私はこれが呼び出すことができると思います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ですが、なぜそれだけではありませんprint for sort { hex $a->[-1] <=> hex $b->[-1] } @hか?hexオペレータは、シュワルツを保証するためにほとんど高価十分である、それはないですか?
ジョセフR. 14年

@JosephR:たぶん、しかし、シュワルツ派はより柔軟で、すべての場合に機能します。処理中に16進値を計算することで別のソリューションが得られると思うので、すぐに回答を更新します。
クオンルム14年

クールなソリューション。このパターンに名前が付けられていることを知りませんでした:decorate-sort-undecorate。上記の私のコメントを参照してください。
ステファン14年

@stefan:更新された回答を参照してください。
クオンルム14年

@Gnouc:はい、あなたの2回目の更新は直接wrtとして決定的に資格があります。私の最初の想像力。
ステファン14

6

このサンプルデータを使用します。

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

考え方は、ソートフィールドを10進数形式で使用して、このデータの新しいバージョンを作成することです。すなわち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

1
ありがとう、かなりクールなソリューション。以前に編集を投稿しなかったことを申し訳ありません。カット+ペーストを使用した同様のアプローチに従います。私は...しかし、より直接的な解決策を期待していた
ステファン・

@stefan「直接」とは何ですか?ソリューションは使用する必要がありますsortか?
ジョセフR. 14年

@Joseph「何が「直接」と見なされますか?」が正しい質問です。基本的に、これまでのすべてのソリューション(Hauke、Gnouc、および私のもの)は同様のことを行います。16進値をデコードし、結果を行に添付し、それでソートし、削除します。デコレート-ソート-デコレートのパターンを使用していないものを探していました。パイプラインで動作するという点で、どちらのソリューションも私のソリューションより優れています。私は個人的にこの種のタスクにPerlよりもawk(小さいハンマー)を使用するため、これを選択しました。
ステファン14年

Gnoucの2回目の更新のため、選択の答えを以下の#3に移動しました。
ステファン14

1

入力

$ cat /tmp/input
0x45 aaa 333
0x50 dd 33
0x4 bbbb 444
0x456 cc 22
0x5 eee 1111

1つのライナーの並べ替え

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1 | cut -f2- -d' '
0x4 bbbb 444
0x5 eee 1111
0x45 aaa 333
0x50 dd 33
0x456 cc 22

ステップごとに並べ替える

ステップ1:16進数の10進表現で新しい最初の列を追加します。

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input 
69 0x45 aaa 333
80 0x50 dd 33
4 0x4 bbbb 444
1110 0x456 cc 22
5 0x5 eee 1111

ステップ2:最初のフィールドで数値的に行を並べ替えます。

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1
4 0x4 bbbb 444
5 0x5 eee 1111
69 0x45 aaa 333
80 0x50 dd 33
1110 0x456 cc 22

ステップ3:最初の列を削除します。

$ gawk  --non-decimal-data '{ dec = sprintf("%d", $1); print dec " "  $0 }' /tmp/input | sort -n -k 1 | cut -f2- -d' '
0x4 bbbb 444
0x5 eee 1111
0x45 aaa 333
0x50 dd 33
0x456 cc 22

0

から適応: http //www.unix.com/302548935-post6.html?s=b4b6b3ed50b6831717f6429113302ad6

:ファイルからソート:

6F993B
954B29
A23F2F
BFA91D
C68C15
8F322F
5A6D40
6D512C
9D9D63
B4B823
A0641C
A79716
A18518

コマンド:

awk '{printf("%050s\t%s\n", toupper($0), $0)}' file-to-sort | LC_COLLATE=C sort -k1,1 | cut -f2

出力:

C68C15
BFA91D
B4B823
A79716
A23F2F
A18518
A0641C
9D9D63
954B29
8F322F
6F993B
6D512C
5A6D40

--toupper($ 0)は小文字を「アップグレード」するため、最初にソートされます(ただし、それが必要かどうかはわかりません)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.