16 진수 값으로 정렬 진수 값 (필드)으로 숫자를 정렬

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-이 물론 다를 수 있음), 그리고 bc진수로 변환을한다 (하지 않고, 대문자 진수를 필요로 0x내 경우 일치하는 접두사). 그런 다음 열을 결합, 정렬 및 분할합니다.



답변

의 해결책 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 진수 값이고 두 번째 요소는 전체 줄입니다.

  • 에서 END블록, 우리는 사용 찌언 변환 :

    • 의 각 요소를 @h사용하여 익명 배열을 만들고 전체 행 ( $_->[1]각 배열의 두 번째 요소 참조 @h)과 16 진수 값을 포함합니다.hex($_->[0])]

    • 16 진수 값을 기준으로 배열 기준으로 정렬 $a->[1] <=> $b->[1]

    • 정렬 된 배열에서 각 배열 참조의 첫 번째 요소를 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 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


답변

입력

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

하나의 라이너 정렬

$ 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


답변

적응 : 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)는 소문자를 “업그레이드”하여 먼저 정렬합니다 (필요하지는 않습니까?)


답변