私は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つの仕上げレベルを無視します。