
Ubuntu 18.04와 기본 coreutils를 사용하고 있습니다. sort
설명하는 방법을 잘 모르는 명령 의 특정 동작을 발견했습니다 .
다음 명령을 고려하십시오.
$ cat <<EOF | sort
0-
01-
EOF
0-
01-
이 출력은 예상되는 것보다 -
ASCII 값이 작기 때문에 의미가 있습니다 .1
그러나 끝에 문자를 하나 더 넣으면 다음과 같습니다.
$ cat <<EOF | sort
0-T
01-T
EOF
01-T
0-T
0-T
이 출력은 내가 먼저 와야 한다고 생각하기 때문에 나에게는 아무런 의미가 없습니다 . 왜 이런 일이 일어나는가? 내가 여기서 무엇을 놓치고 있는 걸까요? 내가 잘못된 기대를 갖고 있는 걸까?
답변1
로케일의 조합 순서에 따라 다릅니다.
대조 순서는 악센트 문자의 순서를 허용하는 각 로케일의 규칙 세트입니다(예: 스페인어의 경우 ñ
뒤에 오고 n
앞에 옵니다 o
).
하지만 그게 다가 아닙니다. 정렬 순서에는 정렬 시 무시할 문자도 명시되어 있습니다. 로케일 "C"의 경우 모든 문자가 고려되지만 예를 들어 "en_US"의 경우 대부분의 다른 로케일과 마찬가지로 대시(U002D)가 무시됩니다. 왜냐하면 iso14651_t1_common(/usr/share/ 아래)에서 정의를 상속하기 때문입니다. 일부 배포판에서는 i18n/locales/).
따라서 첫 번째 파일의 순서는 문제가 되지 않습니다. 대시를 무시하면 간단한 알파벳순 비교로 끝나기 때문입니다.
-- ignore dashes --> -- sort -->
0- 0 0
01- 01 01
"T"를 추가하면 상황이 달라집니다. 이유는 무엇입니까? 이제 대시를 무시하면 "1"과 "T"(첫 번째 문자가 동일함)를 비교해야 하고 "1"이 "T" 앞에 오기 때문입니다.
-- ignore dashes --> -- sort -->
0-T 0T 01T
01-T 01T 0T
따라서 정렬 시 LC_COLLATE=C를 사용하여 항상 "C" 규칙을 사용하고 있는지 확인하는 것이 좋습니다.
귀하의 경우:
$ cat <<EOF | LC_COLLATE=C sort
0-T
01-T
EOF
수익률:
0-T
01-T
예상대로.
답변2
네, 짜증나는 것 같을 수도 있어요. (기본 로케일 en_US.UTF-8)
$ printf '%s\n' 1 1- 1-a 11- 11-a | sort
1
1-
11-
11-a
1-a
그 이유는 이 분류 순서에 -
지정되어 있기 때문입니다 .no weight
"
a가 해야 할 일과 유사합니다 :
printf '%s\n' 1 \"1\" 1- \"1-\" 1-a \"1-a\" 11- \"11-\" 11-a \"11-a\" | sort
"1"
"1-"
1
1-
"11-"
11-
"11-a"
11-a
"1-a"
1-a
위에서 볼 수 있듯이 1개 모두 함께 정렬됩니다 11
. 문제는 다른 어떤 것보다 1-a
더 유사하게 정렬된다는 것입니다 1a
.
printf '%s\n' 1-a 1-b 1-c 1a 1b 1c| sort
1-a
1a
1-b
1b
1-c
1c
이든구두( -
, 및 기타)이 데이터 정렬 정렬 순서에 포함되어야 하는지는 논란의 여지가 있습니다 "
. ;
(ASCII가 아닌 로케일에서는) 그렇게 하면 안 된다는 것이 일반적인 견해였습니다.
그만큼흔한대부분의 라틴 언어에 대한 파일은 /usr/share/i18n/locales/iso14651_t1_common
. 해당 파일에서 HYPHEN-MINUS
(예, 일반인 용어로 dash. Unicode U-002D라고 부르는 것) 대조 순서는 다음과 같이 설정됩니다.
<U002D> IGNORE;IGNORE;IGNORE;<U002D> % HYPHEN-MINUS
즉, 대조의 처음 세 가지 수준을 무시합니다.