5

区切り文字を指定しても、UNIX数値ソートは奇妙な結果をもたらします。

$ cat example.csv  # here's a small example
58,1.49270399401
59,0.000192136419373
59,0.00182092924724
59,1.49270399401
60,0.00182092924724
60,1.49270399401
12,13.080339685
12,14.1531049905
12,26.7613447051
12,50.4592437035

$ cat example.csv | sort -n --field-separator=,
58,1.49270399401
59,0.000192136419373
59,0.00182092924724
59,1.49270399401
60,0.00182092924724
60,1.49270399401
12,13.080339685
12,14.1531049905
12,26.7613447051
12,50.4592437035

この例では、区切り文字を指定しても、sort は同じ結果を返します。LC_ALL=C設定した場合、並べ替えが再び期待される動作を開始することはわかっています。しかし、以下に示すように、デフォルトの環境設定でこれが発生する理由がわかりません。

$ locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=

私は他の多くの質問 (たとえば、ここここ、およびここ) からこの動作を回避する方法を読みましたが、それでも、この動作は信じられないほど奇妙で予測不可能であり、1 週間の心痛を引き起こしました。Mac OS X (10.8.5) のデフォルトの環境設定で並べ替えがこのように動作する理由を誰か説明できますか? 言い換えれば、その結果を得るために (ローカル変数を en_US.UTF-8 に設定して) sort は何をしているのでしょうか?

私は使用しています

 sort 5.93                        November 2005

 $ type sort
 sort is /usr/bin/sort

アップデート

これについては gnu-coreutils リストで説明しましたが、英語の Unicode デフォルト ロケール設定で並べ替えを行うと出力が得られる理由がわかりました。英語の unicode では、コンマ文字 "," は数値と見なされ (コンマを 1000 単位 (または 100 単位など) の区切り記号として使用できるようにするため)、行を解釈するときに sort の既定値は "貪欲である" ため、次の例を読み取ります。おおよその数字

581.491...
590.000...
590.001...
591.492...
600.001...
601.492...
1213.08...
1214.15...
1226.76...
1250.45...

これは私が意図したものではありませんでしたが、chepner が正しい結果を得るには、最初のフィールドのみをキーとして並べ替えるように指定する必要があります。sort デフォルトでは、最初のフィールドだけをキーとして解釈するのではなく、行全体をキーとして解釈します。

sort のこの動作は gnu-coreutil のFAQで議論されており、sort の POSIX 記述でさらに指定されています。

そのため、 gnu-coreutil のリストにある Eric Blake が述べているように、フィールド セパレータも数値 (カンマ) の場合、「-k を使用しないと、[フィールド セパレータ] は両方のセパレータとして機能します。 AND 数字 - 複数のフィールドにまたがる数字でソートしています。」

4

3 に答える 3