Pet*_*r.O 10 text-processing sort unicode locale uniq
以下代码片段中发生了什么?我没有得到预期的输出。
我认为这是一个错误,但它发生在 2 个不同的程序(uniq 和 sort)中,所以我怀疑这与……嗯,我不知道是什么……因此问题。
前 3 个(共 4 个)示例有效,但第 4 个失败!。
我希望任何和所有角色都有相同的行为。
IE。打印出 2 行(来自 3 行输入)...但在第 4 种情况下,我只得到 1 行(对于sort -u
和uniq
);两个相同的林斯消失了!
为了视图的紧凑性,我已将输出 '\n' 转换为空间。
我使用的uniq和排序从(GNU的coreutils)7.4 ...的Ubuntu 10.04.3 LTS桌面上运行。
剧本:
{
locale -k LC_COLLATE
echo
for c1 in x ? ;do
for c2 in z ? ;do
echo -n "asis : "; echo -e "$c1\n$c2\n$c2" |tr '\n' ' ';echo
echo -n "uniq : "; echo -e "$c1\n$c2\n$c2" |uniq |tr '\n' ' ';echo
echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
echo
done
echo
done
}
Run Code Online (Sandbox Code Playgroud)
输出:
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"
asis : x z z
uniq : x z
sort -u: x z
asis : x ? ?
uniq : x ?
sort -u: ? x
asis : ? z z
uniq : ? z
sort -u: ? z
asis : ? ? ?
uniq : ?
sort -u: ?
# In the last example (of 4) where did the '?' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 12
简短版本:排序规则在命令行实用程序中不起作用。
更长的版本:比较两个字符串的底层函数是strcoll
. 描述不是很有帮助,但操作的概念方法是将两个字符串转换为规范形式,然后比较两种规范形式。该函数strxfrm
构造了这种规范形式。
让我们观察一些字符串的规范形式(使用 GNU libc,在 Debian 挤压下):
$ export LC_ALL=en_US.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' b a A à ? ?
b d010801020
a c010801020
A c010801090
à 101010102c6b
? 101010102c6b102c6b102c6b
? 101010102c6b102c6b102c6b
Run Code Online (Sandbox Code Playgroud)
如你看到的, ?和 ?具有相同的规范形式。我认为这是因为在en_US.UTF-8
语言环境的校对表中没有提到这些字符。但是,它们存在于日本语言环境中。
$ export LC_ALL=ja_JP.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' ? ?
? 303030
? 3c9b
Run Code Online (Sandbox Code Playgroud)
区域设置数据(在 Debian 压缩中)的源代码在 中/usr/share/i18n/locales/en_US
,其中包括/usr/share/i18n/locales/iso14651_t1_common
. 这个文件没有U3007
or的条目U303C
,它们也不包含在我能找到的任何范围内。
符号 UNDEFINED 应解释为包括所有未明确指定或通过省略号指定的编码字符集值。(...) 如果未指定 UNDEFINED 符号,并且当前编码字符集包含本节中未指定的字符,则实用程序应发出警告消息并将此类字符放在字符整理顺序的末尾。
看起来 Glibc 会忽略未指定的字符。我不知道我对 POSIX 规范的理解是否存在缺陷,是否我遗漏了 Glibc 的语言环境定义中的某些内容,或者 Glibc 语言环境编译器中是否存在错误。
小智 6
要“安全地” sort
Unicode 字符串,也许看看msort
:
[...] Msort 提供了更大的选择键字段的灵活性、更多的比较类型、在不同键上使用来自不同区域设置的整理规则的能力、在非西方数字系统中处理数字的能力以及各种其他缺乏的选项在 GNU 排序和 BSD 排序中。msort 理解 Unicode,而 GNU sort 和 BSD sort 不理解。[...]
http://www.billposer.org/Software/msort.html