一種の奇妙な行動[繰り返し]

一種の奇妙な行動[繰り返し]

私は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

したがって、ソート時には常に「C」ルールを使用し、LC_COLLATE = 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

aがやるべきことに似たもの"

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もちろん、allも一緒にソートされます。問題は、次のように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ソート順は次のように設定されます(たとえば、一般人の用語ではdash.Unicode U-002Dと呼ばれます)。

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

つまり、最初の3つの仕上げレベルを無視します。

関連情報