Dra*_*nis 27 sort unicode locale
?(“拉丁语 epsilon”)是某些非洲语言中使用的字母,通常表示英语“bed”中的元音。在 Unicode 中,它被编码为 U+025B,与日常非常不同e。
但是,如果我sort执行以下操作:
eb
ed
?a
?c
Run Code Online (Sandbox Code Playgroud)
似乎sort考虑?和e等效:
?a
eb
?c
ed
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?有没有一种方法可以为ing 目的制作?和e区分sort?
Sté*_*las 68
不,它不认为它们是等效的,它们只是具有相同的主要权重。因此,在第一个近似值中,它们的排序相同。
如果您查看 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
您会注意到,有相当多的字符定义了完全相同的 4 个权重。特别是,我们的 ? 具有相同的权重:
<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE
Run Code Online (Sandbox Code Playgroud)
果然:
$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
?
$ expr ? = ?
1
Run Code Online (Sandbox Code Playgroud)
这可以看作是 GNU libc 语言环境的错误。在大多数其他系统上,语言环境确保所有不同的字符最终具有不同的排序顺序。在GNU语言环境中,它会变得更糟,因为有成千上万没有排序顺序,并最终排序相同的字符,造成各种问题(如破comm,join,ls或具有不确定性令水珠... ),因此建议使用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
Run Code Online (Sandbox Code Playgroud)
(为什么 U+00B7 仅在与L/组合时才被视为与 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
Run Code Online (Sandbox Code Playgroud)
(仍然超过 100 万个字符(Unicode 范围的 95%,低于 2.27 中的 98%)排序与其他字符相同,因为它们的排序顺序未定义)。
也可以看看:
Ipo*_*cer 15
男人排序:
*** 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.
Run Code Online (Sandbox Code Playgroud)
所以,试试: LC_ALL=C sort file.txt
人物 ?不等于 e,但一些语言环境可以在整理后将这些标志聚集在一起。其原因是语言特定的,但也有一些历史甚至政治背景。例如,大多数人可能期望在字典中€uro 货币接近欧洲。
无论如何,要查看您当前使用的排序规则 run locale,locale -a它将为您提供系统上可用的语言环境列表,并将排序规则更改为C仅用于一次排序运行LC_COLLATE=C sort file。最后看看不同的语言环境如何对您的文件进行排序,请尝试
for loc in $(locale -a)
do echo ____"${loc}"____
LC_COLLATE="$loc" sort file
done
Run Code Online (Sandbox Code Playgroud)
将结果传送到一些 gring 工具以选择适合您需要的语言环境。
| 归档时间: |
|
| 查看次数: |
4367 次 |
| 最近记录: |