
를 사용하여 일부 데이터를 정렬하려고 합니다 sort
. 숫자가 아닌 숫자로 정렬되는 것을 확인하여 플래그를 추가했습니다 -n
. 그런 다음 겉보기에는 첫 번째 필드에서만 숫자로만 정렬됩니다. 라인에 다양한 수의 필드가 있으므로 필드별로 분류하는 것은 문제가 됩니다(솔직히 그 동작을 이해할 수 없습니다). 다음은 제가 가지고 놀았던 충분히 근접한 샘플 데이터입니다:
echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" | sort -n
Input Want Expect? sort -n -n -k1,1 -k2,2 -k3,3 -k4,4…
b b 1 8 2 a 1 23 44 a 1 b a 1
23 44 8 15 a 7 23 9 a 7 b a 10
b 3 23 9 b a 1 8 15 b 1 b a 2
a 7 23 44 b a 2 8 2 b 10 b b 1
b b 2 a 1 b a 10 a 1 b 2 b b 10
a 1 a 7 b b 1 a 7 b 3 b b 2
b a 10 b 1 b b 2 b 1 b a 1 a 1
b b 10 b 2 b b 10 b 10 b a 10 b 1
b 1 b 3 b 1 b 2 b a 2 b 2
b a 1 b 10 b 2 b 3 b b 1 b 3
8 2 b a 1 b 3 b a 1 b b 10 a 7
b 10 b a 2 b 10 b a 10 b b 2 b 10
8 15 b a 10 8 2 b a 2 8 15 8 2
b a 2 b b 1 8 15 b b 1 8 2 8 15
23 9 b b 2 23 9 b b 10 23 44 23 9
b 2 b b 10 23 44 b b 2 23 9 23 44
이상적으로는 GNU coreutils 정렬 5.93이 있는 바로 그 컴퓨터에서 작동하게 하고 싶습니다. 나는 간단한 유닉스 도구를 사용하여 이를 처리하고 싶습니다. 나는 문제를 Perl 등에 넘겨주고 싶지 않습니다. 나는 [가상]과 동등한 것을 기대하고 있습니다.sort --numeric-sort --all-fields --actually-work
답변1
sort
나는 당신이 무엇을 하고 있는지 이해하지 못하는 것이 문제라고 생각합니다 . 기본 정렬은 ASCII 문자 값을 기반으로 하며 숫자는 대문자 앞에 있고 소문자 앞에 있습니다: '1' == 49, 'A' == 65, 'a' = 97. 이는 sort
'23과 같은 숫자가 있는 열을 설명합니다. '는 'b b' 이전인 '8' 앞에 정렬됩니다. '2'의 ASCII 값은 50이고, '8'의 ASCII 값은 56이고 'b'의 ASCII 값은 98입니다.
숫자로 정렬할 때( sort -n
), 숫자가 아닌 항목은 일반 방법으로 정렬되지만 23이나 8과 같은 숫자와 비교하면 0으로 해석됩니다. 하지만 문자값이 아닌 숫자로 처리되기 때문에 '8'이 '23' 앞에 옵니다. 따라서 알파벳 항목이 숫자 항목보다 먼저 정렬됩니다.
가장 좋은 방법은 각 열이 동일한 유형의 값(모두 숫자 또는 모두 영숫자)을 갖도록 데이터를 정규화하고 적절하게 정렬하는 것입니다.
마지막 열(필드 기준 정렬)에서는 명시적으로 4개(또는 그 이상) 필드를 지정하므로 더 많은 필드가 있는 항목을 먼저 정렬합니다. 따라서 (1,2,3)은 (1,2)보다 앞에 있을 것입니다. 옵션이 없으면 -k
정렬은 라인 전체를 고려합니다.
자세한 내용은정보 코어 유틸리티 정렬페이지.
답변2
echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n18 2\nb 10\n18 15\nb a 2\n23 9\nb 2" \
| sed -r 's/[a-z]/9999&/g' | sort -n -k1 -k2 -k3 | sed 's/9999//g'
18 2
18 15
23 9
23 44
a 1
b 1
b 2
b 3
a 7
b 10
b a 1
b b 1
b a 2
b b 2
b a 10
b b 10
당신이 원하는 게 바로 이것인가요? 숫자인 경우 숫자로 정렬하고 다른 문자 앞에 숫자를 정렬하시겠습니까?
모든 문자열 앞에 높은 숫자를 붙여 정렬을 통해 문자열을 마지막에 배치하고 마지막에 높은 숫자(9999)를 제거합니다.
답변3
수년간의 개발을 통해 얻은 이점을 바탕으로 sort -V
on은 sort 8.26
원하는 결과를 생성합니다.
$ echo -e "b b 1\n23 44\nb 3\na 7\nb b 2\na 1\nb a 10\nb b 10\nb 1\nb a 1\n8 2\nb 10\n8 15\nb a 2\n23 9\nb 2" \
| sort -V
8 2
8 15
23 9
23 44
a 1
a 7
b 1
b 2
b 3
b 10
b a 1
b a 2
b a 10
b b 1
b b 2
b b 10