C
LC_ALL
Unixシリーズシステムでの価値はどのような役割を果たしますか?
私はそれがすべての点で同じロケールを使用するように強制することを知っていますが、それは何をしますかC
?
答え1
LC_ALL
他のすべてのローカライズ設定をオーバーライドする環境変数($LANGUAGE
特定の状況を除いて)。
一部の環境変数を使用して、ローカライゼーションのさまざまな側面(たとえば、千単位の区切り文字または小数点文字、文字セット、ソート順、月、曜日名、言語、またはアプリケーションメッセージ(エラーメッセージ、通貨記号など)を設定できます。 。
通常、$LANG
好みに応じて地域を識別する値を設定します。たとえば、fr_CH.UTF-8
フランス語を話すスイスに住んでいる場合は、UTF-8を使用します。各LC_xxx
変数は特定の側面を扱います。LC_ALL
すべて覆ってください。引数なしで呼び出すと、locale
コマンドは現在の設定の概要を提供します。
たとえば、GNUシステムでは、次のような結果が得られます。
$ locale
LANG=en_GB.UTF-8
LANGUAGE=
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC="en_GB.UTF-8"
LC_TIME="en_GB.UTF-8"
LC_COLLATE="en_GB.UTF-8"
LC_MONETARY="en_GB.UTF-8"
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT="en_GB.UTF-8"
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=
次の個々の設定を上書きできます。
$ LC_TIME=fr_FR.UTF-8 date
jeudi 22 août 2013, 10:41:30 (UTC+0100)
または:
$ LC_MONETARY=fr_FR.UTF-8 locale currency_symbol
€
あるいは、LC_ALLを使用してすべてを上書きします。
$ LC_ALL=C LANG=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8 cat /
cat: /: Is a directory
スクリプトがユーザーがどの設定を強制したのか(LC_ALLかもしれません)、わからないので、特定の設定を強制したい場合に最適で安全で、しばしば唯一のオプションはLC_ALLを強制することです。
locale はC
特別なロケールであり、最も単純なロケールです。他のロケールは人間用であり、Cロケールはコンピュータ用であるとも言えます。 Cロケールでは、文字はシングルバイトで、文字セットはASCII(もちろん必須ではありませんが、実際に私たちのほとんどが使用しているシステムにあります)で、ソート順はバイト値1に基づいており、言語は通常アメリカ英語です(アプリケーションメッセージの(月や日の名前、またはシステムライブラリからのメッセージとは対照的に)アプリケーションの作成者の裁量によって異なります。通貨記号などは定義されていません。
一部のシステムでは、非ASCII文字のソート順序が定義されていないなど、POSIXロケールとは異なります。
通常、ユーザー設定がスクリプトを妨げないようにするには、LC_ALL = Cでコマンドを実行します。たとえば、から[a-z]
26文字のASCII文字を一致させるには、この項目を設定する必要があります。a
z
LC_ALL=C
GNUシステムでは、およびLC_ALL=C
(LC_ALL=POSIX
またはLC_MESSAGES=C|POSIX
)はオーバーライドされますが$LANGUAGE
、そうではLC_ALL=anything-else
ありません。
一般的に設定する必要がある状況は次のとおりですLC_ALL=C
。
sort -u
またはsort ... | uniq...
。 C以外の多くの言語といくつかのシステム(特にGNUシステム)では一部の文字のソート順は同じです。。sort -u
一意の行を報告するのではなく、並べ替え順が同じ行セットごとに1つずつ報告されます。したがって、一意の行が本当に必要な場合は、文字がバイトであり、すべての文字が異なるソート順序を持つロケールが必要です(ロケールC
保証)。2つの文字列が同じかどうかは、チェックせずに等しくソートされているかどうかを確認する
=
POSIX準拠演算子expr
または==
POSIX準拠演算子(awk
その問題はPOSIXではmawk
ない)にも同じことが当てはまります。gawk
。などの文字範囲を
grep
ユーザーの言語の文字と一致させるには、を使用してgrep '[[:alpha:]]'
変更しないでくださいLC_ALL
。ただし、ASCII文字を一致させるにはor²がa-zA-Z
必要です。前後にソートされた文字と一致します(多くのAPIの場合、状況はこれよりも複雑ですが)。他の地域では、それが何であるかわからないことがよくあります。たとえば、一部のロケールはソート時に大文字と小文字を無視するため、一部のAPI(スキーマなど)には、またはを含めることができます。多くのUTF-8ロケール(ほとんどのシステムを含む)には、分音符付きのtoからのラテン文字が含まれますが、分音符付きの文字は含まれません(以前)。これがあなたが望むものであるとは想像できません。含めますか?)LC_ALL=C grep '[[:alpha:]]'
LC_ALL=C grep '[a-zA-Z]'
[a-z]
a
z
[a-z]
bash
[B-Z]
[A-Y]
en_US.UTF-8
[a-z]
a
y
z
z
é
ź
の浮動小数点演算
ksh93
。設定をksh93
尊重してください。埋め込みスクリプトを作成すると、ロケールが小数点区切りでコンマを使用しているユーザーが実行すると動作が停止します。decimal_point
LC_NUMERIC
a=$((1.2/7))
$ ksh93 -c 'echo $((1.1/2))' 0.55 $ LANG=fr_FR.UTF-8 ksh93 -c 'echo $((1.1/2))' ksh93: 1.1/2: arithmetic syntax error
その後、次のようなものが必要です。
#! /bin/ksh93 -
float input="$1" # get it as input from the user in his locale
float output
arith() { typeset LC_ALL=C; (($@)); }
arith output=input/1.2 # use the dot here as it will be interpreted
# under LC_ALL=C
echo "$output" # output in the user's locale
注:,
小数点区切り記号は,
算術演算子と衝突し、より多くの混乱を招く可能性があります。
文字をバイトに変換する必要があるとき。今日、ほとんどのロケールはUTF-8に基づいており、これは文字が1〜6バイト³を占有できることを意味します。テキストユーティリティを使用してバイトデータを処理する場合は、LC_ALL = Cを設定する必要があります。また、UTF-8データの解析にコストがかかるため、パフォーマンスが大幅に向上します。
前のポイントの結果:テキストを処理するときに入力がどの文字セットで書かれたのかわかりませんが、ASCII互換であると仮定できます(ほとんどの文字セットの場合と同様)。たとえば、UTF-8ロケールにあり、入力が単一バイトの8ビット文字セット(たとえばiso8859-15)でエンコードされている場合、ペアを含む
grep '<.*>'
行を見つけることは<
機能しません。これは、iso8859-15で一致する文字、非ASCII文字のみがUTF-8で有効な文字を形成できない可能性が高い>
ためです。.
一方、LC_ALL=C grep '<.*>'
すべてのバイト値はロケールで有効な文字を形成するために機能しますC
。いつでも、人間または人間以外の起源ではない入力データまたは出力データを処理します。ユーザーと会話する場合は、ユーザーのルールと言語を使用したいと思います。ただし、たとえば、英語スタイルの小数点または英語の月名を必要とする他のアプリケーションに供給するための数値を生成する場合は、次のようにします。 LC_ALL=C に設定するには:
$ printf '%g\n' 1e-2 0,01 $ LC_ALL=C printf '%g\n' 1e-2 0.01 $ date +%b août $ LC_ALL=C date +%b Aug
grep -i
これは、大文字と小文字を区別しない比較(たとえばin)と大文字と小文字の変換(awk
's toupper()
、...)にも当てはまりますdd conv=ucase
。たとえば、
grep -i i
I
ユーザーロケールの一致は保証されません。たとえば、一部のトルコ語ロケールでは、大文字i
(İ
ドット参照)や小文字I
(ı
欠落点を参照)のようには見えません。
ノート
繰り返しますが、これはASCIIベースのシステム(ほとんどのシステム)でのみ機能します。 POSIXstrcoll()
では、Cロケールの===最適化を許可しないEBCDICシステムでも、Cロケールの組み合わせ順序がASCII文字セットの文字順序になるように要求します。strcmp()
²テキストエンコーディングによっては、これが必ずしも正しいアプローチではないかもしれません。これはUTF-8またはシングルバイト文字セット(iso-8859-1など)で機能しますが、UTF-8以外のマルチバイト文字セットでは必ずしもそうではありません。
たとえば、特定の地域(BIG5中国語文字エンコーディングの香港バリアントを使用する香港)にあり、zh_HK.big5hkscs
その文字セットでエンコードされたファイル内の英語文字を検索する場合は、次のいずれかを実行します。
LC_ALL=C grep '[[:alpha:]]'
または
LC_ALL=C grep '[a-zA-Z]'
その文字セット(および他の多くの文字セット(UTF-8の出現以来ほとんど使用されていません))に多くの文字が含まれているため、間違っています。含むA-Za-z文字に対応するASCIIでエンコードされたバイト。たとえば。をA䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
含むすべて(およびそれ以上)は0x96 0x41であり、これはASCIIと同様に0x41です。したがって、これらのバイトシーケンスを誤って解釈する可能性があるため、これらの文字を含む行を一致させます。A
䨝
A
LC_ALL=C grep '[a-zA-Z]'
LC_COLLATE=C grep '[A-Za-z]'
動作しますが、LC_ALL
他に設定しない場合にのみ可能です(この値は上書きされますLC_COLLATE
)。したがって、最終的には次のことを行う必要があります。
grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'
ロケールエンコーディングでエンコードされたファイルでアルファベットを見つけたい場合。
3一部の人々はUnicodeコードポイント(およびUTF-8データをエンコード/デコードするライブラリ)がコードポイントU + 0000〜U + 10FFFF(0xD800〜0xDFFFを除く)にランダムに制限されているため、長さは1〜1であると主張しています。 UTF-16エンコーディングに対応するにはU + 7FFFFFFFから4バイトが必要ですが、一部のアプリケーションではまだ6バイトUTF-8シーケンス(0xD800 .. 0xDFFF範囲に属するシーケンスを含む)をエンコード/デコードできます。
答え2
これは、アプリケーションが出力にデフォルト言語を使用することを強制します。
$ LC_ALL=es_ES man
¿Qué página de manual desea?
$ LC_ALL=C man
What manual page do you want?
そして強制的にバイト順序を指定します。
$ LC_ALL=en_US sort <<< $'a\nb\nA\nB'
a
A
b
B
$ LC_ALL=C sort <<< $'a\nb\nA\nB'
A
B
a
b
答え3
C
はデフォルトのロケールで、「POSIX」は「C」のエイリアスです。 「C」はANSI-Cから派生したようです。おそらく、ANSI-Cは「POSIX」ロケールを定義できます。
答え4
また、LC_COLLATE
lsで使用する「アルファベット順」を制御しているようです。米国のロケールは次のように並べ替えられます。
a.C
aFilename.C
aFilename.H
a.H
ピリオドはデフォルトで無視されます。あなたは以下を好むかもしれません:
a.C
a.H
aFilename.C
aFilename.H
当然知っている。これを完了するLC_COLLATE
には設定してくださいC
。すべての大文字の後に小文字もソートされます。
A.C
A.H
AFilename.C
a.C
a.H