ɛ
(“拉丁 epsilon”)是某些非洲语言中使用的字母,通常代表英语“bed”中的元音。在 Unicode 中,它的编码为 U+025B,与日常使用的非常不同e
。
但是,如果我sort
执行以下操作:
eb
ed
ɛa
ɛc
看来sort
考虑ɛ
和e
等价:
ɛa
eb
ɛc
ed
这里发生了什么?有没有办法使ɛ
和e
区分 为sort
ing 目的?
答案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 语言环境中,情况变得更糟,因为有数千个字符没有排序顺序,最终排序相同,导致各种问题(例如破坏comm
, join
,ls
具有不确定顺序的 glob... ),因此建议使用LC_ALL=C
解决这些问题。
正如 @ninjalj 在评论中指出的,2018 年 8 月发布的 glibc 2.28 在这方面进行了一些改进,尽管 AFAICS 仍然存在一些使用相同排序顺序定义的字符或整理元素。在使用 glibc 2.28 且语言环境为 en_GB.UTF-8 的 Ubuntu 18.10 上。
$ 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 万个字符(Unicode 范围的 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 工具,以选择适合您需要的区域设置。