なぜGnuソートが私のOSXシステムとLinuxシステムで異なってソートされるのですか?

なぜGnuソートが私のOSXシステムとLinuxシステムで異なってソートされるのですか?

sortsortcoreutils 8.26(Homebrewからインストール)でGNUを実行するOSXシステムと、sortcoreutils 8.25でGNUを実行するLinuxシステムがあります。sort

Macの場合:

mac$ echo -e "{1\n2" | sort
2
{1

Linuxの場合:

linux$ echo -e "{1\n2" | sort
{1
2

私はそれがsort地域によって異なることを知っています。localeLinuxシステムで実行し、出力の各行を先頭に追加し、OSXexportシステムで結果行を実行してから(同じ端末で)sortコマンドを再実行して、以前と同じ出力を提供しました。

localeしかし、Macで実行すると、Linuxに表示されるすべての行が表示されないことがわかりました。これが関連しているかどうかはわかりません。

Linuxのロケール:

linux$ locale
LANG=en_CA.UTF-8
LANGUAGE=en_CA:en
LC_CTYPE="en_CA.UTF-8"
LC_NUMERIC="en_CA.UTF-8"
LC_TIME="en_CA.UTF-8"
LC_COLLATE="en_CA.UTF-8"
LC_MONETARY="en_CA.UTF-8"
LC_MESSAGES="en_CA.UTF-8"
LC_PAPER="en_CA.UTF-8"
LC_NAME="en_CA.UTF-8"
LC_ADDRESS="en_CA.UTF-8"
LC_TELEPHONE="en_CA.UTF-8"
LC_MEASUREMENT="en_CA.UTF-8"
LC_IDENTIFICATION="en_CA.UTF-8"
LC_ALL=en_CA.UTF-8

OSXのロケール:

mac$ locale
LANG="en_CA.UTF-8"
LC_COLLATE="en_CA.UTF-8"
LC_CTYPE="en_CA.UTF-8"
LC_MESSAGES="en_CA.UTF-8"
LC_MONETARY="en_CA.UTF-8"
LC_NUMERIC="en_CA.UTF-8"
LC_TIME="en_CA.UTF-8"
LC_ALL="en_CA.UTF-8"

LC_ALL=C両方のコンピュータに設定すると、両方が以前に2ソートされていることがわかりました{1。ただし、LC_ALL=en_CA.UTF-82台のコンピュータに設定すると、上記のように異なる結果が表示されます。LC_ALL=en_CA.utf82台のコンピュータに設定した場合も同様です。 (Linux システムにはリストされますが、locale -aOSX システムにはリストされません.)en_CA.utf8en_CA.UTF-8

何が起こっているのか知っていますか?

答え1

前回同じ問題についてもう少し調べたことがあり、技術的な回答を共有します。


macOS /usr/share/locale/en_US.UTF-8/LC_COLLATE(またはen_CA.UTF-8同じもの)は、/usr/share/locale/la_LN.US-ASCII/LC_COLLATE次から派生したシンボリックリンクです。la_LN.US-ASCII.srcそしてcolldef。以下は専門ですla_LN.US-ASCII.src

# ASCII
#
# $FreeBSD: src/share/colldef/la_LN.US-ASCII.src,v 1.2 1999/08/28 00:59:47 peter Exp $
#
order \
    \x00;...;\xff

LC_COLLATEチェックサムをチェックして、バイナリが実際に作成されたことを確認できますla_LN.US-ASCII.src

$ colldef -o /dev/stdout usr-share-locale.tproj/colldef/la_LN.US-ASCII.src | sha256sum
9ec9b40c837860a43eb3435d7a9cc8235e66a1a72463d11e7f750500cabb5b78  -

$ sha256sum </usr/share/locale/en_US.UTF-8/LC_COLLATE
9ec9b40c837860a43eb3435d7a9cc8235e66a1a72463d11e7f750500cabb5b78  -

ルールセットは理解しやすいです。バイト値を1つずつ比較するだけです。したがって、組み合わせはen_US.UTF-8POSIXロケール(Cロケールとも呼ばれます)と同じです。{0x7Bで、20x32なので{一番後ろにあります2

このルールセットはFreeBSD 5の製品で、Mac OS X 10.3 Pantherと同期しています。バラよりcolldefFreeBSD 5.0.0ソースツリーのディレクトリ。それ以来、OS X / macOSでは変更されていません。


Linuxでは、ロケールプログラムとデータについてはglibcglibcを参照してください。localedata/localesまたは/usr/share/i18n/localesDebian/Ubuntuで。を確認すると、ルールに従うことが/usr/share/i18n/locales/en_USわかります。だから、iso14651_t1_commonLC_COLLATEISO 14651ルールを整理してください。


詳しくはブログ投稿:https://blog.zhimingwang.org/macos-lc_collat​​e-hunt

関連情報