これは、これらの文字が同じ並べ替え順序を持っているためです。
また、それに気づくでしょう
sort -u << EOF
■
⅕
⅖
⅗
EOF
1行のみを返します。
またはその:
expr ■ = ⅕
(POSIXで要求されるように)trueを返します。
GNUシステムに同梱されているほとんどのロケールには、同じ並べ替え順序を持つ多数の文字(および文字のシーケンス(照合シーケンス)もあります)があります。これらの■⅕⅖⅗のものの場合、それは順序が定義されておらず、順序が定義されていない文字がGNUシステムで同じソート順序を持つことになります。sortingやlikeのように同じソート順を持つと明示的に定義されている文字があります(ただし、実際のロジックやその方法に関する一貫性は明らかではありませんが)。
それは非常に驚くべき、偽の行動の原因です。私はごく最近、オースティングループ(POSIXおよびSingle UNIX Specificationの背後にある団体)メーリングリストでこの問題を提起しましたが、2015-04-03の時点でまだ議論が続いています。
この場合は、どうか[y]
と一致する必要がありx
どこx
とy
同じを並べ替える私には不明であるが、ブラケット表現は、ことを示唆している照合要素、一致することを意図しているので、bash
動作が期待されているが。
いずれにせよ、[⅕-⅕]
少なくとも[⅕-⅖]
一致する必要があり■
ます。
さまざまなツールの動作が異なることに気付くでしょう。ksh93振る舞うようbash
GNU、grep
またはsed
しないでください。他のいくつかのシェルにはyash
、さらにバグが多いような異なる動作があります。
一貫した動作を実現するには、すべての文字のソートが異なるロケールが必要です。Cロケールは典型的なものです。ただし、ほとんどのシステムのCロケールの文字セットはASCIIです。GNUシステムでは、通常C.UTF-8
、UTF-8文字で作業する代わりに使用できるロケールにアクセスできます。
そう:
(export LC_ALL=C.UTF-8; [[ ■ = [⅕⅖⅗] ]])
または標準的な同等物:
(export LC_ALL=C.UTF-8
case ■ in ([⅕⅖⅗]) true;; (*) false; esac)
falseを返す必要があります。
別の選択肢はLC_COLLATE
、GNUシステムで動作するC のみに設定することですが、マルチバイト文字のソート順の指定に失敗する可能性がある他のシステムでは必ずしもそうではありません。
その教訓の1つは、文字列の比較に関して、平等は期待するほど明確な概念ではないということです。平等とは、最も厳しいものから最も厳しいものまでを意味する場合があります。
- 同じバイト数とすべてのバイト構成要素は同じ値を持ちます。
- 同じ文字数とすべての文字は同じです(たとえば、現在の文字セットの同じコードポイントを参照します)。
- 2つの文字列の並べ替え順序は、ロケールの照合アルゴリズムと同じです(つまり、a <bもb> aもtrueではありません)。
現在、2または3の場合、両方の文字列に有効な文字が含まれていると想定しています。UTF-8およびその他のエンコーディングでは、バイトのシーケンスによっては有効な文字が形成されません。
そのため、またはいくつかの文字が複数の可能なエンコーディングを持っている可能性があるため、1と2は必ずしも同等ではありません。これは通常、ISO-2022-JPのようなステートフルエンコーディングの場合だA
と表現することができる41
か1b 28 42 41
(1b 28 42
私はかかわらず、違いをすることはありませんスイッチにシーケンスでASCIIにし、あなたが望むようにそれらの多くとして挿入することができ、)これらのタイプのエンコーディングがまだ使用中であるとは思わないでしょうし、GNUツールは少なくともそれらと一緒に正しく動作しません。
また、ほとんどの非GNUユーティリティは0バイト値(ASCIIのNUL文字)を処理できないことに注意してください。
これらの定義のどちらが使用されるかは、ユーティリティとユーティリティの実装またはバージョンによって異なります。POSIXはそのことについて完全に明確ではありません。Cロケールでは、3つすべてが同等です。そのYMMVの外。