以下のコードスニペットでは何が起こっていますか?期待した結果が得られませんでした。
私はこれがバグだと思いますが、2つの異なるプログラム(uniqとsort)で発生するので、これが何か関連していると思われます...まあ、何が起こっているのかわかりません...したがって問題が発生します。
最初の3つ(4つのうち)の例は機能しますが、4番目の例は失敗します!
私はすべてのキャラクターが同じように行動したいと思います。
つまり。 (入力3行のうち)2行を印刷します...しかし、4番目の場合は1行だけを取得します(合計の場合sort -u
)uniq
。 2つの同じ行が消えます。
ビューを簡潔に保つために、出力 '\ n'を空白に変換しました。
私はそれを使用していますユニークそしてタイプ(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
#
答え1
ショートバージョン:コマンドラインユーティリティでは、照合順序は実際には機能しません。
より長いバージョン:2つの文字列を比較する基本関数は次のとおりです。strcoll
。説明はあまり役に立ちませんが、概念的にこれを行う方法は、2つの文字列を標準形式に変換してから2つの標準形式を比較することです。機能strxfrm
この正式な形式が構成されます。
いくつかの文字列の標準形式を見てみましょう(Debian squeezeでGNU libcを使用)。
$ 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
includeにあります。このファイルには、またはエントリが/usr/share/i18n/locales/iso14651_t1_common
なく、私が見つけることができる範囲には含まれていません。U3007
U303C
私は慣れていないソートルール設定ルールしかし、私が理解したところによると、関連表現は次のようになります。
UNDEFINEDシンボルは、明示的に指定されていないか省略記号で指定されていないすべてのエンコードされた文字セット値を含むと解釈されます。 (...)未定義のシンボルが指定されておらず、現在エンコードされている文字セットにこのセクションに指定されていない文字が含まれている場合、ユーティリティは警告メッセージを発行し、その文字を文字ソート順序の末尾に配置する必要があります。
Glibcは指定されていない文字を無視するようです。 POSIX仕様の理解に欠陥があるのか、Glibcロケール定義に欠けている部分があるのか、Glibcロケールコンパイラにバグがあるのかはわかりません。
答え2
Unicode文字列を「安全に」使用するには、sort
次の点を見てくださいmsort
。
[...] Msortは、キーフィールドの選択、より多くの比較タイプ、異なるキーから異なるロケールの照合順序を使用する機能、非西欧数値システムの数値を処理する機能、およびその他のさまざまなオプションの面で不足しています。より大きな柔軟性を提供します。 GNUソートとBSDソート。 msortはUnicodeを理解していますが、GNUソートとBSDソートは理解していません。 [...]