web-dev-qa-db-ja.com

sortはなぜɛ= eと言うのですか?

ɛ( "ラテンイプシロン")は、特定のアフリカの言語で使用される文字で、通常は英語の「ベッド」で母音を表します。 Unicodeでは、これはU + 025Bとしてエンコードされ、日常のeとは非常に異なります。

ただし、次の場合はsortです。

eb
ed
ɛa
ɛc

sortɛeを同等と見なしているようです:

ɛa
eb
ɛc
ed

何が起きてる?そして、eingの目的でɛsortを区別する方法はありますか?

26
Draconis

いいえ、それはそれらを同等とは見なしません、それらは同じ主要な重みを持っているだけです。したがって、最初の近似では、それらは同じようにソートされます。

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、_ɛ_とEは同じプライマリウェイト、eEは同じセカンダリウェイトですが、3番目のウェイトだけがそれらを区別します。

文字列を比較するとき、sortstrcoll()標準libc関数は文字列の比較に使用されます)はすべての文字のプライマリウェイトを比較することから始まり、文字列が等しい場合にのみ2番目のウェイトに進みますプライマリウェイト(他のウェイトも同様)。

このようにして、最初の近似の並べ替え順序で大文字と小文字が無視されるように見えます。 Abaaacの間でソートしますが、Abは言語ルールに応じてabの前または後にソートできます(一部の言語では_<MIN>_の前に_<CAP>_の前にイギリス英語のように、一部の_<CAP>_の前に_<MIN>_のようにエストニア語のように)。

eの並べ替え順序が_ɛ_と同じ場合、_printf '%s\n' e ɛ | sort -u_は1行だけを返します。ただし、_<BAS>_は_<PCL>_の前にソートされるため、eだけがbefore_ɛ_の前にソートされます。 _eɛe_はEEEEEE(3番目の重みに達する必要がある)の後にソートされる場合でも、eeeの後に(2番目の重みで)ソートします。

ここで、glibc 2.27を使用するシステムで次のコマンドを実行します。

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

まったく同じ4つの重みで定義されている文字がかなりあることに気づくでしょう。特に、ourの重みは次のとおりです。

_<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ロケールのバグと見なすことができます。他のほとんどのシステムでは、ロケールは、すべての異なる文字が最後に異なるソート順を持っていることを確認します。OnGNU =ロケールの場合、並べ替え順序がなく、同じように並べ替えられてしまう文字が何千もあり、あらゆる種類の問題(commjoinlsまたは非決定論的な順序を持つglobs ...)、つまり _LC_ALL=C_を使用してこれらの問題を回避する の推奨。

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

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

(なぜ、U + 00B7は、L/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%から減少))並べ替え順序が定義されていないため、他の文字と同じように並べ替えられます)。

以下も参照してください。

67

男の並べ替え:

   ***  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

15
Ipor Sircer

文字ɛはeと等しくありませんが、一部のロケールでは、照合時にこれらの標識を互いに近くに集めることができます。この理由は、言語固有ですが、歴史的または政治的な背景もあります。たとえば、ほとんどの人はおそらくユーロ通貨が辞書のヨーロッパに近づくことを期待しています。

とにかく、現在使用している照合順序を確認するには、localelocale -aは、システムで使用可能なロケールのリストを提供し、照合順序をCに変更して、1回のソートを実行しますLC_COLLATE=C sort file。最後に、さまざまなロケールがファイルを並べ替える方法を確認します

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

結果を何らかの手探りツールにパイプして、ニーズに合ったロケールを選択します。

8
jimmij