ソートがɛ=eだと言うのはなぜですか?

ソートがɛ=eだと言うのはなぜですか?

ɛ(「ラテンエプシロン」)は、いくつかのアフリカ言語で使用される文字であり、しばしば英語「bed」のコレクションを表します。 UnicodeのエンコーディングはU + 025Bであり、これは日常的に使用されるエンコーディングとは大きく異なりますe

ただし、sort次のようにすると:

eb
ed
ɛa
ɛc

sort考慮ɛして同等だと思われますe

ɛa
eb
ɛc
ed

ここで何が起こっているのでしょうか?目的に合わせて差別化ɛするe方法はありますか?sort

答え1

いいえ、等しいとは見なされず、基本的な重みは同じです。したがって、最初の近似では、順序は同じです。

GNUシステム(ここではglibc 2.27が使用されています)で/usr/share/i18n/locales/iso14651_t1_common(ほとんどのロケールの基礎として使用されています)を見ると、次のことがわかります。

<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E

e、同じプライマリウェイトと同じセカンダリウェイトをɛ持ち、3番目のウェイトのみを区別します。EeE

文字列を比較するとsortstrcoll()文字列比較用の標準libc関数)、すべての文字のデフォルトの重みが最初に比較され、2番目の重みは文字列がデフォルトの重みと同じ場合にのみ比較されます(他の重みと同じ)。

これが最初の近似ソートで大文字と小文字が無視される方法です。との間に並べ替えられますが、Ab言語の規則に従って前後に並べ替えることができます(一部の言語は英国英語のように前であり、一部の言語はエストニア語のように前です)。aaacAbab<MIN><CAP><CAP><MIN>

eソート順序が同じ場合、1行だけが返されます。しかし、先に述べたように、この一人で並べるとɛprintf '%s\n' e ɛ | sort -u<BAS><PCL>e今後 ɛeɛe後でソート(2番目の重み)、その後にソートされていてEEEも(これを行うには3番目の重みに移動する必要があります)EEEeee

今私のシステムでglibc 2.27を使用している場合は、次のようにします。

sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
  sort -k2 | uniq -Df1

かなり多くの文字がまったく同じ4つの重みで定義されていることがわかります。特に、ɛの重みは同じです。

<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE

本当に:

$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1

これはGNU libcロケールのバグとして見ることができます。他のほとんどのシステムでは、ロケール設定により、すべての文字が異なるソート順序を持つようになります。 GNUロケールでは、ソート順のない何千もの文字が最終的に同じようにソートされ、すべての種類の問題(例:broken comm、、未定義の順序を持​​つglob...)が発生するため、状況joinls悪化するため推奨されます。以下を使用して、LC_ALL=Cこれらの問題を解決します。

@ninjaljがコメントで指摘したように、glibc 2.28の2018年8月のリリースにはいくつかの改善点がありますが、AFAICSにはまだ同じソート順序を使用して定義されているいくつかの文字または照合順序要素があります。 Ubuntu 18.10では、glibc 2.28とロケールen_GB.UTF-8を使用します。

$ expr $'L\ub7' = $'L\u387'
1

L(U + 00B7が/と結合されている場合にのみU + 0387と同じと見なされるのはなぜですかl?!)

そして:

$ perl -lC -e 'for($i=0; $i<0x110000; $i++) {$i = 0xe000 if $i == 0xd800; print chr($i)}' | sort > all-chars-sorted
$ uniq -d all-chars-sorted | wc -l
4
$ uniq -D all-chars-sorted | wc -l
1061355

(ソート順が定義されていないため、他の文字と同じようにソートされている文字はまだ100万個を超えています(Unicode範囲の95%、2.27の98%から減少)。

また見なさい:

答え2

男性分類:

   ***  WARNING  ***  The locale specified by the environment affects sort
   order.  Set LC_ALL=C to get the traditional sort order that uses native
   byte values.

したがって、次のことを試してください。LC_ALL=C sort file.txt

答え3

ɛ文字はeと同じではありませんが、一部のロケールでは、組み合わせるとこれらの記号を一緒に囲むことができます。その理由は言語によって異なりますが、特定の歴史的、さらには政治的文脈もあります。たとえば、ほとんどの人はユーロ近いヨーロッパ事前に。

とにかく、現在の実行がどの照合順序を使用しているかを確認するためにシステムで使用可能なロケールのリストを提供し、一度の並べ替え実行にのみ使用されるように照合順序をlocale変更します。最後に、さまざまなロケールがファイルを並べ替える方法を見てみましょう。locale -aCLC_COLLATE=C sort file

for loc in $(locale -a)
    do echo ____"${loc}"____
    LC_COLLATE="$loc" sort file
done

結果をgrepツールにパイプして、ニーズに合ったロケールを選択します。

関連情報