Ні, це не вважає їх рівнозначними, вони просто мають однакову основну вагу. Так що в першому наближенні вони сортують те саме.
Якщо ви подивитесь на / usr / share / i18n / locales / iso14651_t1_common (як це використовується як основа для більшості локалів) у системі GNU (тут із glibc 2.27), ви побачите:
<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 локалей, це стає ще гірше, так як є тисячі символів , які не мають порядку сортування і в кінцевому підсумку сортування же, в результаті чого всіх видів проблем (наприклад , розбиваються comm
, join
, ls
або грудки , що мають недетерміновані замовлення ... ), отже, рекомендація щодо використання LC_ALL=C
для вирішення цих питань .
Як зазначає @ninjalj у коментарях, glibc 2.28, опублікований у серпні 2018 року, прийшов з деякими вдосконаленнями на цьому фронті, хоча AFAICS, все ж є деякі символи або збірні елементи, визначені в однаковому порядку сортування. У Ubuntu 18.10 з glibc 2.28 та у локальній мові en_GB.UTF-8.
$ expr $'L\ub7' = $'L\u387'
1
(чому U + 00B7 вважатиметься еквівалентом U + 0387 лише у поєднанні з L
/ 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
.
Дивись також: