我的 `uniq` 或 `sort -u` 行哪里去了,有一些 unicode 字符

Pet*_*r.O 10 text-processing sort unicode locale uniq

以下代码片段中发生了什么?我没有得到预期的输出。

我认为这是一个错误,但它发生在 2 个不同的程序(uniq 和 sort)中,所以我怀疑这与……嗯,我不知道是什么……因此问题。

前 3 个(共 4 个)示例有效,但第 4 个失败!。

我希望任何和所有角色都有相同的行为。
IE。打印出 2 行(来自 3 行输入)...但在第 4 种情况下,我只得到 1 行(对于sort -uuniq);两个相同的林斯消失了!

为了视图的紧凑性,我已将输出 '\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. 这个文件没有U3007or的条目U303C,它们也不包含在我能找到的任何范围内。

我不熟悉构建整理顺序规则,但据我了解,相关措辞是

符号 UNDEFINED 应解释为包括所有未明确指定或通过省略号指定的编码字符集值。(...) 如果未指定 UNDEFINED 符号,并且当前编码字符集包含本节中未指定的字符,则实用程序应发出警告消息并将此类字符放在字符整理顺序的末尾。

看起来 Glibc 会忽略未指定的字符。我不知道我对 POSIX 规范的理解是否存在缺陷,是否我遗漏了 Glibc 的语言环境定义中的某些内容,或者 Glibc 语言环境编译器中是否存在错误。

  • *排序*和*独特*方面在`LC_COLLATE = C`之前工作正常......谢谢...... (2认同)

小智 6

要“安全地” sortUnicode 字符串,也许看看msort

[...] Msort 提供了更大的选择键字段的灵活性、更多的比较类型、在不同键上使用来自不同区域设置的整理规则的能力、在非西方数字系统中处理数字的能力以及各种其他缺乏的选项在 GNU 排序和 BSD 排序中。msort 理解 Unicode,而 GNU sort 和 BSD sort 不理解。[...]

http://www.billposer.org/Software/msort.html