我的 uniq
或 sort -u
行去了哪裡,帶有一些 unicode 字元
以下程式碼片段中發生了什麼?我沒有得到預期的輸出。
我認為這是一個錯誤,但它發生在 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 }
輸出:
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 #
簡短版本:排序規則在命令行實用程序中並不真正起作用。
更長的版本:比較兩個字元串的底層函式是
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
如您所見,〼和〇具有相同的規範形式。我認為這是因為在
en_US.UTF-8
語言環境的整理表中沒有提到這些字元。但是,它們存在於日本語言環境中。$ export LC_ALL=ja_JP.UTF-8 $ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' 〼 〇 〼 303030 〇 3c9b
語言環境數據(在 Debian Squeeze 中)的原始碼位於 中
/usr/share/i18n/locales/en_US
,其中包括/usr/share/i18n/locales/iso14651_t1_common
. 該文件沒有U3007
or的條目U303C
,也不包含在我能找到的任何範圍內。我不熟悉建立排序規則的規則,但據我了解,相關的措辭是
符號 UNDEFINED 應解釋為包括所有未明確指定或通過省略號符號指定的編碼字元集值。(…) 如果未指定 UNDEFINED 符號,並且目前編碼字元集包含本節未指定的字元,則實用程序應發出警告消息並將此類字元放在字元排序順序的末尾。
看起來 Glibc 忽略了未指定的字元。我不知道我對 POSIX 規範的理解是否存在缺陷,是否遺漏了 Glibc 語言環境定義中的某些內容,或者 Glibc 語言環境編譯器中是否存在錯誤。