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
10진수로 변환합니다(대소 0x
문자를 일치시키려면 접두어 없이 대문자 16진수가 필요함). 그런 다음 열을 연결하고 정렬하고 분할합니다.
최소 샘플 입력:
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
답변1
나는 다음 샘플 데이터를 사용합니다.
1 hdh d12
2 ukr 9f
3 ezh ae
4 jjk 7
5 hhf 25
아이디어는 십진수 형식의 정렬 필드를 사용하여 이 데이터의 새 버전을 생성하는 것입니다. 즉, awk
1 변환하여 각 행의 앞에 추가하고 결과를 정렬한 다음 마지막 단계에서 추가된 필드를 제거합니다.
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 이는 GNU awk
기능을 가정합니다 strtonum()
.
답변2
해결책 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],$_]
, 첫 번째 요소는 비교할 16진수 값이고, 두 번째 요소는 전체 라인입니다.END
우리가 사용하는 블록 에서는슈워츠 변환:각 요소를 사용하여
@h
전체 행($_->[1]
각 배열 참조의 두 번째 요소@h
)과 비교할 16진수 값을 포함하는 익명 배열을 만듭니다.hex($_->[0])]
16진수 값을 기준으로 위 배열을 정렬합니다.
$a->[1] <=> $b->[1]
정렬된 배열에서 각 배열 참조의 첫 번째 요소를 가져오고
map { $_->[0] }
결과를 인쇄합니다.
고쳐 쓰다
@Joseph R의 제안을 바탕으로:
$ perl -anle '
push @h, [hex($F[-1]),$_];
END {
print $_->[1] for
sort { $a->[0] <=> $b->[0] } @h;
}
' file
업데이트 2
Schwartzian 변환을 사용하지 않고 Stefan의 의견을 읽은 후:
$ 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
답변3
입력하다
$ 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
답변4
sort -g
16진수 값을 정렬할 수 있습니다. 0x
접두사 가 필요합니다 .
awk '{ $3 = "0x" $3; print }' sample.txt |
sort -g -k3 |
awk '{ $3 = gensub(/^0x/, "", 1, $3); print }'
0x
세 번째 열에 추가하기 전에- 범용 숫자 정렬 옵션을 사용하여 세 번째 열을 기준으로 정렬
0x
세 번째 열에서 삭제