「uniq」または「sort -u」行がどこにあるのか、いくつかのユニコード文字がある


10

次のコードスニペットで何が起こっていますか?期待どおりの出力が得られません。

バグだと思いますが、2つの異なるプログラム(uniqとsort)で発生するので、何か関係があるのではないかと思います。

最初の3つ(4つのうち)の例は機能しますが、4番目の例は失敗します。

すべてのキャラクターで同じ動作が期待されます。
すなわち。(入力の3行から)2行を出力するには... 4番目のケースでは、1行しか表示されません(sort -uおよびの両方uniq)。2つの同一のリンが消えるだけです!

表示をコンパクトにするために、出力「\ 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
#

注意してください ..明確にするために。sort単独で(-uオプションなしで)...文字を取得しません..何が入ってくるかが出てきます...しかし、同じ標準値を持つ「エキゾチックな」ユニコード文字のGillesの説明から予想されるように、これらは文字は並べ替えられませんが、並べ替えの出力の「先頭」に並べ替えられていないFIFOグループとして出力されます...したがって、実際には2つの問題があります:1.文字が「単純に」並べ替えられない両方のユニークな『機能」期待、そして2』と(場合によっては)失うデータ。sortuniq
Peter.O

アップデート:ASは言及ジル(ロケール固有のソートは必須ではなく、文字の順序が適切である)、sort -uそしてuniq仕事の罰金と: LC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u(または|uniq
Peter.O

回答:


11

ショートバージョン:コマンドラインユーティリティでは照合順序は実際には機能しません。

長いバージョン:2つの文字列を比較するための基になる関数はstrcollです。説明はあまり役に立ちませんが、操作の概念的な方法は、両方の文字列を標準形式に変換してから、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、これにはが含まれています/usr/share/i18n/locales/iso14651_t1_common。このファイルには、のエントリを持っていないU3007U303C、また彼らは、私が見つけることができる任意の範囲に含まれています。

照合順序を作成するためのルールに精通していませんが、私が理解していることから、関連する表現は

記号UNDEFINEDは、明示的にまたは省略記号を介して指定されていないすべてのコード化文字セット値を含むものとして解釈されます。(…)UNDEFINEDシンボルが指定されておらず、現在のコード化文字セットにこのセクションで指定されていない文字が含まれている場合、ユーティリティは警告メッセージを発行し、そのような文字を文字照合順序の最後に配置します。

Glibcが指定されていない文字を無視しているようです。POSIX仕様の理解に欠陥があるのか​​、Glibcのロケール定義に何か欠けているのか、またはGlibcロケールコンパイラにバグがあるのか​​はわかりません。


@ギルズ:有益で詳細な説明をありがとう..ある程度は理にかなっていますが、ソートを「安全に」使用する方法は疑問です。特に、「ロケールに依存する」ソートではないので、ソートはそれを行います...これの簡単な回避策はありますか?...そして徐々にこつこつになりますが、「一晩」は起こりません...例。/ usr / share / i18n / charmaps / UTF-8には、問題の両方の文字への参照が含まれています、しかし、このUTF-8定義(?)にあることは役に立たないようです...さて、まあ、小さな謎のない生活はどのようなものでしょうか。:) ...
Peter.O

1
@fred charmaps/UTF-8は照合について何も言わない、それlocales/en_USが問題だ。の最初のルールは、をLC_COLLATE使用しないことLC_COLLATEです。C(= POSIX)ロケールでは、照合は妥当です(厳密に数値の値に基づいています)。
Gilles「SO-邪悪なことをやめなさい」

2
ソートユニークなアスペクト細かい作業が先行したときにLC_COLLATE=C...ありがとう...
Peter.O

1
照合がユーティリティで機能しないということではありませんが、glibcロケールの設計が不十分です。その動作は(現在ですが、austingroupbugs.net / view.php?id = 1070を参照してください)POSIXで許可されていますが、残念ながら望ましくありません。
ステファンChazelas

6

「安全に」sortUnicode文字列を確認するには、次を参照してmsortください。

[...] Msortは、キーフィールドを選択する際の柔軟性を高め、比較タイプを増やし、さまざまなキーのさまざまなロケールの照合ルールを使用する機能、非西洋の数値システムで数値を処理する機能、およびその他のさまざまなオプションを欠いていますGNUソートとBSDソートで。msortはUnicodeを理解しますが、GNUソートとBSDソートは理解しません。[...]

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


@til:を知らせてくれてありがとうmsort。オプションのGUIを使用すると、紹介の内容が少しわかりやすくなります。生成されたコマンドをコピーできることは非常に便利です...そして、はい、それはユニコード文字をソートします が、(あなたはそれらの「お尻」だけが好きではありません:)...しかし、それはユニークなオプションを持っていません: (...あなたが投稿したリンクで述べたように:Capabilities of GNU sort and BSD sort lacking in msort are the ability to merge files without sorting them (the --merge option) and the ability to emit only the first of an equal run (the --unique option)...ソートは動作します:)
Peter.O
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.