コンテキスト

コンテキスト
  • コンテキスト
  • 問題発見
    • 質問番号1
    • 質問番号2
    • 質問番号3
  • 質問

コンテキスト

今日は、ファイル内の漢字を含む唯一の行を維持したいと思います。sort私はこのユーティリティに慣れていて、ファイルから重複行を削除するのがこのフラグを使用するのと同じくらい簡単なので、このユーティリティを使用することにしました-usort漢字を正しく使用するには、ロケールを変更する必要があることを学びました。私は別のロケールを使ってsort異なる動作を見つけました。この記事では、私が見つけた結果を紹介します。

ファイルから重複した行を削除することは、複数のツール/プログラミング言語を使用して実行できることを認識しています。これを行うためのツールを提案したすべての人に感謝しますが、ロケールについてさらに学び、これがUnixユーティリティにどのような影響を及ぼすかに興味があります。

問題発見

質問番号1

以下は私のシステムのロケール設定です。

locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

次の名前を考えてください。main.txt


私のen_US.UTF-8$LANG番号を失いました。 2

sort -u main.txt

LANG設定でこの問題を解決しましたzh_CN.UTF-8

export LANG=zh_CN.UTF-8
sort -u main.txt

私が作る一つの質問スタックオーバーフローに関するこの質問について。誰かがロケールを変えようと提案したのに効果があるようで問題が解決されたと思ったが後で見たら問題ではないですね。 2と質問番号。 3(以下の説明)。

質問番号2

それでは、ファイルに2行を追加するとしましょう。main.txt


ベストアンサー1

sort -u出力は、ロケールで同じように(同じソート順に)照合される各行セットの1つです。

GNUシステム(GNU libcを使用するシステム)では、ほとんどのロケールで多くの文字1が定義されていないソート順序を持ち、これは最終的に同じ順序であることを意味し、同じソート順序を持つように明示的に定義された文字もあります。

バイトをテキストとしてデコードできない場合、通常は無視されるか、同じソート順序²を持つと見なされます。

したがって、sort -uバイト対バイト同等の比較に基づいて一意の行を提供するには、テキストがどのエンコーディングで書かれたかにかかわらず、各バイトを文字としてデコードできるロケールと完全な順序付きロケールが必要です。

最も簡単な方法は、Cバイト==文字マップを持つロケールを使用することです(特定のバイトははっきりしない文字)、ソートはバイト値(少なくともASCIIベースのシステムでは)に基づいており、特定のシステムで見つけることができる唯一のロケールです。

あなたがより良い動作を提供する理由を理解するには、一般的にGNUシステムで見つけることができるロケール定義をzh_CN見てください。ここで以下を見つけることができます。/usr/share/i18n/localezh_CN

LC_COLLATE
copy "iso14651_t1_pinyin"
END LC_COLLATE

どこiso14651_t1_pinyin

copy "iso14651_t1_common"

en_US次に、多くの追加の中国語文字の並べ替えを指定しますiso14651_t1_common

zh_CN.GB18030またはzh_CN.GBKに設定LC_CTYPE(配信LANG)してUTF-8sortでエンコードされたファイルを処理しようとすると、通常UTF-8でエンコードされたテキストのバイトがエンコードされないため、その行をテキストにデコードできません。 GB18030エンコーディングで有効なフォーマットを設定すると、問題がさらに悪化します。

ここで一意の(バイト対バイト比較による)行を取得しようとすると同時に、そのロケールで「正しく」ソートされた出力を取得するには、次のようにします。

LC_ALL=C sort -u your-file | sort

1 つ目はsort重複項目を削除し、2 つ目はロケールのソート規則に従って残りの行をソートします。

LC_ALL代わりにLANGor LC_CTYPE+を使用するLC_COLLATE理由は、この変数がすべてをオーバーライドする変数(whichよりも優先されます)であるためですLC_ALLLC_individual_settingしたがって、LANGorが環境に異なる方法で設定されていても、LANGまだLC_COLLATE機能します。

理論的には、次のようにすることもできます。

LC_ALL= LC_CTYPE=C LC_COLLATE=C sort

「文字タイプ」および「組み合わせ」設定のみが設定され、他のロケールカテゴリはそのままに(またはとして上書きさLANGれてLC_xxx)使用される残りのカテゴリは、たとえばエラーメッセージsort用です。設定すると、USのみが使用されます。とにかく英語のメッセージはASCII文字のみを含むため、正しく表示されます。たとえば、LC_MESSAGESLC_CTYPE=C

$ LC_MESSAGES=zh_CN LC_CTYPE=C sort --version
sort (GNU coreutils) 9.1
Copyright (C) 2022 Free Software Foundation, Inc.
??? GPLv3+:GNU ???????? 3 ?????? <https://gnu.org/licenses/gpl.html>?
????????:??????????????
?????????,????????

? Mike Haertel ? Paul Eggert ???

詳細は以下で確認できます。


厳密に言えば基本単位ではない。特徴しかし、要素の構成chたとえば、特定のチェコ地域間hまたは内部で複数の類似した文字で構成できます。i

sort² GNU以外のいくつかの実装sortでは、NUL文字または過度に長い行もブロックされます。

おすすめ記事