![정렬이 ɛ = e라고 말하는 이유는 무엇입니까?](https://linux55.com/image/141135/%EC%A0%95%EB%A0%AC%EC%9D%B4%20%C9%9B%20%3D%20e%EB%9D%BC%EA%B3%A0%20%EB%A7%90%ED%95%98%EB%8A%94%20%EC%9D%B4%EC%9C%A0%EB%8A%94%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
ɛ
("라틴 엡실론")은 일부 아프리카 언어에서 사용되는 문자로, 종종 영어 "bed"의 모음을 나타냅니다. 유니코드의 인코딩은 U+025B이며 이는 일상적으로 사용되는 인코딩과 매우 다릅니다 e
.
그러나 sort
다음을 수행하면:
eb
ed
ɛa
ɛc
sort
고려 ɛ
하고 동등하다고 생각됩니다 e
:
ɛa
eb
ɛc
ed
여기서 무슨 일이 일어나고 있는 걸까요? 목적 에 맞게 ɛ
만들고 e
차별화할 수 있는 방법이 있나요 ?sort
답변1
아니요, 동등하다고 간주하지 않으며 기본 가중치가 동일할 뿐입니다. 따라서 첫 번째 근사치에서는 순서가 동일합니다.
GNU 시스템(여기에서는 glibc 2.27이 사용됨)에서 /usr/share/i18n/locales/iso14651_t1_common(대부분의 로케일의 기초로 사용됨)을 보면 다음을 볼 수 있습니다.
<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E
e
, 동일한 기본 가중치 와 동일한 보조 가중치를 ɛ
가지며 세 번째 가중치만 구별됩니다.E
e
E
문자열을 비교할 때 sort
( strcoll()
문자열 비교를 위한 표준 libc 함수) 모든 문자의 기본 가중치가 먼저 비교되고, 두 번째 가중치는 문자열이 기본 가중치와 동일한 경우에만 비교됩니다(다른 가중치와도 마찬가지).
이것이 첫 번째 근사 정렬에서 대소문자가 무시되는 방식입니다. 와 사이에 정렬되지만 Ab
언어 규칙에 따라 앞이나 뒤에 정렬될 수 있습니다(일부 언어는 영국 영어처럼 앞이고 일부 언어는 에스토니아어처럼 앞입니다).aa
ac
Ab
ab
<MIN>
<CAP>
<CAP>
<MIN>
의 e
정렬 순서가 동일한 경우 하나의 행만 반환됩니다. 하지만 앞서 말했듯 이 혼자서 정렬하면ɛ
printf '%s\n' e ɛ | sort -u
<BAS>
<PCL>
e
앞으로 ɛ
. eɛe
이후에 정렬 (두 번째 가중치), 이후에 정렬된 EEE
경우에도 (이를 위해서는 세 번째 가중치로 이동해야 함)EEE
eee
이제 내 시스템에서 glibc 2.27을 사용하는 경우 다음을 실행합니다.
sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
sort -k2 | uniq -Df1
꽤 많은 문자가 정확히 동일한 4가지 가중치로 정의되어 있음을 알 수 있습니다. 특히 ɛ의 가중치는 동일합니다.
<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE
정말:
$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1
이는 GNU libc 로케일의 버그로 볼 수 있습니다. 대부분의 다른 시스템에서는 로케일 설정을 통해 모든 문자가 서로 다른 정렬 순서를 갖게 됩니다. GNU 로케일에서는 정렬 순서가 없는 수천 개의 문자가 결국 동일하게 정렬되어 모든 종류의 문제(예: broken comm
, join
, ls
정의되지 않은 순서가 있는 glob...)를 일으키기 때문에 상황이 더 악화되므로 권장됩니다.다음을 사용하여 LC_ALL=C
이러한 문제를 해결하십시오..
@ninjalj가 의견에서 지적했듯이 glibc 2.28의 2018년 8월 릴리스에는 이와 관련하여 몇 가지 개선 사항이 있지만 AFAICS에는 여전히 동일한 정렬 순서를 사용하여 정의된 일부 문자 또는 데이터 정렬 요소가 있습니다. Ubuntu 18.10에서 glibc 2.28 및 로케일 en_GB.UTF-8을 사용합니다.
$ expr $'L\ub7' = $'L\u387'
1
L
(U+00B7이 /와 결합된 경우에만 U+0387과 동일한 것으로 간주되는 이유는 무엇입니까 l
?!)
그리고:
$ perl -lC -e 'for($i=0; $i<0x110000; $i++) {$i = 0xe000 if $i == 0xd800; print chr($i)}' | sort > all-chars-sorted
$ uniq -d all-chars-sorted | wc -l
4
$ uniq -D all-chars-sorted | wc -l
1061355
(정렬 순서가 정의되지 않았기 때문에 다른 문자와 동일하게 정렬되는 문자가 여전히 100만 개가 넘습니다(유니코드 범위의 95%, 2.27의 98%에서 감소).
또한보십시오:
답변2
남성 분류:
*** WARNING *** The locale specified by the environment affects sort
order. Set LC_ALL=C to get the traditional sort order that uses native
byte values.
따라서 다음을 시도해 보십시오.LC_ALL=C sort file.txt
답변3
ɛ 문자는 e와 동일하지 않지만 일부 로케일에서는 조합할 때 이러한 기호를 함께 묶을 수 있습니다. 그 이유는 언어별로 다르지만 특정 역사적, 심지어 정치적 맥락도 있습니다. 예를 들어 대부분의 사람들은유로화가까운유럽사전에.
어쨌든, 현재 실행이 어떤 데이터 정렬을 사용하고 있는지 확인하기 위해 시스템에서 사용 가능한 로케일 목록을 제공하고 한 번의 정렬 실행에만 사용되도록 데이터 정렬을 locale
변경 합니다 . 마지막으로, 다양한 로캘이 파일을 정렬하는 방법을 살펴보겠습니다.locale -a
C
LC_COLLATE=C sort file
for loc in $(locale -a)
do echo ____"${loc}"____
LC_COLLATE="$loc" sort file
done
결과를 grep 도구로 파이프하여 필요에 맞는 로케일을 선택하십시오.