ある種の奇妙な行動

ある種の奇妙な行動

私は Ubuntu 18.04 とデフォルトの coreutils を使用しています。sortコマンドの特定の動作に気付きましたが、どのように説明すればよいかわかりません。

次のコマンドを考えてみましょう。

$ cat <<EOF | sort
0-
01-                                    
EOF
0-
01-

この出力は意味をなします。-は ASCII 値よりも小さいため1、この出力が予想されます。

ただし、最後にもう 1 文字追加すると、次のようになります。

$ cat <<EOF | sort
0-T
01-T
EOF
01-T
0-T

この出力は、最初に来るはずだと思うので、私には意味がわかりません0-T。なぜこのようなことが起こるのでしょうか。ここで何が欠けているのでしょうか? 間違った期待を抱いているのでしょうか?

答え1

ロケールの照合順序によって異なります。

照合順序は、アクセント付き文字の順序付けを可能にする各ロケールの一連のルールです (たとえば、スペイン語ではアクセント付き文字ñは後になりますnが、アクセント付き文字は前になりますo)。

しかし、それだけではありません。照合順序は、ソート時に無視される文字も指定します。ロケール「C」の場合、すべての文字が考慮されますが、たとえば「en_US」の場合、ダッシュ (U002D) は無視されます。これは、他のほとんどのロケールと同様に、iso14651_t1_common (一部のディストリビューションでは /usr/share/i18n/locales/ の下) から定義を継承しているためです。

したがって、ダッシュを無視すると単純なアルファベット順の比較になるため、最初のファイルの順序付けは問題になりません。

      -- ignore dashes -->      -- sort --> 
0-                          0               0
01-                         01              01 

「T」を追加すると、状況が変わります。なぜでしょうか? ダッシュを無視すると、「1」と「T」(最初の文字は同じ) を比較する必要があり、「1」が「T」の前に来るからです。

      -- ignore dashes -->      -- sort --> 
0-T                          0T               01T
01-T                         01T              0T

したがって、ソート時に LC_COLLATE=C を使用して、常に「C」のルールを使用していることを確認することをお勧めします。

あなたの場合:

$ cat <<EOF | LC_COLLATE=C sort
0-T
01-T
EOF

結果:

0-T
01-T

予想通りですね。

答え2

はい、面倒に思えるかもしれません。(デフォルトのロケールは en_US.UTF-8 です)

$ printf '%s\n' 1 1- 1-a 11- 11-a | sort
1
1-
11-
11-a
1-a

その理由は、照合順序に-が割り当てられているためです。no weight

次のようなことを"実行する必要があります。

printf '%s\n' 1 \"1\" 1- \"1-\" 1-a \"1-a\" 11- \"11-\" 11-a \"11-a\" | sort
"1"
"1-"
1
1-
"11-"
11-
"11-a"
11-a
"1-a"
1-a

上の図からわかるように、1 はすべて一緒にソートされ、すべても11同様です。問題は、他のものよりも1-aソートされていることです。1a

printf '%s\n' 1-a 1-b 1-c 1a 1b 1c| sort
1-a
1a
1-b
1b
1-c
1c

かどうか句読点( -、、"その他;) を照合順序に含めるべきかどうかは議論の的となっています。一般的な見解は、(非 ASCII ロケールでは) 含めるべきではないというものでした。

一般ほとんどのラテン系言語のファイルは です/usr/share/i18n/locales/iso14651_t1_common。そのファイルでは、HYPHEN-MINUS(そう、私たちが俗にダッシュと呼んでいるものです。Unicode U-002D) 照合順序は次のように設定されています。

<U002D> IGNORE;IGNORE;IGNORE;<U002D> % HYPHEN-MINUS

つまり、照合の最初の 3 つのレベルを無視します。

関連情報