UnixライクなシステムでのC
価値は何LC_ALL
ですか?
私はそれがすべての面で同じロケールを強制することを知っていますが、何をしC
ますか?
UnixライクなシステムでのC
価値は何LC_ALL
ですか?
私はそれがすべての面で同じロケールを強制することを知っていますが、何をしC
ますか?
回答:
アプリケーションが出力にデフォルト言語を使用するように強制します。
$ 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
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を強制することです。
C
ロケールは、最も単純なロケールであることを意味する特別なロケールです。また、他のロケールは人間用であるのに対し、Cロケールはコンピューター用であると言うこともできます。Cロケールでは、文字は1バイトで、文字セットはASCIIです(そうする必要はありませんが、実際にはほとんどの人が使用するシステムになります)。並べ替え順序はバイト値に基づいています。言語は通常、米国英語(アプリケーションメッセージ(月や曜日の名前やシステムライブラリによるメッセージなど)ではなく、アプリケーション作成者の裁量による)であり、通貨記号などは定義されていません。
一部のシステムでは、たとえば非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
ロケールはそれを保証します)。=
準拠したPOSIXのオペレータexpr
や==
POSIX準拠したのオペレータawk
S(mawk
およびgawk
その点ではPOSIXされていない)、2つの文字列が同一であるが、それらが同じかどうかを並べ替えるかどうかを確認しません。grep
。ユーザーの言語の文字と一致させる場合は、を使用しgrep '[[:alpha:]]'
、変更しないでくださいLC_ALL
。ただし、a-zA-Z
ASCII文字を一致させるには、LC_ALL=C grep '[[:alpha:]]'
またはLC_ALL=C grep '[a-zA-Z]'
¹のいずれかが必要です。前後に[a-z]
ソートされる文字に一致します(ただし、多くのAPIではそれよりも複雑です)。他のロケールでは、一般にそれらが何であるかわかりません。たとえば、一部のロケールではソートの大文字と小文字が区別されないため、パターンなどの一部のAPI では、またはを含めることができます。(を含む多くのUTF-8ロケールではほとんどのシステムで)、からラテン文字が含まれますには発音区別符号ではなく、それらの(以来、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
補足説明として、,
小数点記号は,
算術演算子と競合するため、さらに混乱を招く可能性があります。
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
)や大文字と小文字の変換(awk
's toupper()
、dd conv=ucase
...)などにも当てはまります。例えば:
grep -i i
I
ユーザーのロケールで一致することが保証されていません。例えば、いくつかのトルコ語のロケールでは、大文字としてないi
でİ
(ドットに注意)が存在し、小文字I
であるı
(ドット抜けに注意します)。
¹テキストのエンコーディングによっては、必ずしも正しいこととは限りません。これはUTF-8またはシングルバイト文字セット(iso-8859-1など)で有効ですが、必ずしも非UTF-8マルチバイト文字セットではありません。
たとえば、zh_HK.big5hkscs
ロケール(香港、香港版のBIG5中国語文字エンコードを使用)で、その文字セットでエンコードされたファイルで英語の文字を探したい場合、次のいずれかを実行します。
LC_ALL=C grep '[[:alpha:]]'
または
LC_ALL=C grep '[a-zA-Z]'
その文字セット(および他の多くの、しかしUTF-8が登場して以来ほとんど使用されていない)では、多くの文字にA-Za-z文字のASCIIエンコードに対応するバイトが含まれているため、間違っています。たとえば、すべてA䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
(およびそれ以上)のエンコーディングが含まれていますA
。䨝
0x96 0x41でありA
、ASCIIのように0x41です。したがって、LC_ALL=C grep '[a-zA-Z]'
これらのバイトシーケンスを誤って解釈するため、これらの文字を含む行で一致します。
LC_COLLATE=C grep '[A-Za-z]'
動作しますが、がLC_ALL
設定されていない場合にのみ有効です(これによりがオーバーライドされますLC_COLLATE
)だからあなたはやらなければならないことになるかもしれません:
grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'
ロケールのエンコーディングでエンコードされたファイルで英語の文字を探したい場合。
C
ロケールは「ポータブル文字セット」(ASCII 0-127)をサポートするためにのみ必要であり、chars> 127の動作は技術的に指定されていません。実際には、ほとんどのプログラムはそれらを不透明なデータとして扱い、説明したとおりに通過させます。ただし、すべてではありません。特に、C
ロケールで実行している場合、Rubyはバイト数が127を超えるcharデータで停止することがあります。正直に言って、それが技術的に「適合」しているかどうかはわかりませんが、実際に見てきました。
perl
、S「は、\x{7FFFFFFFFFFFFFFF}
Unicodeコードポイントの範囲を任意にU + 10FFFFに制限されているが)と(UTF-16の設計上の制限により)、いくつかのツールはまだ6バイト文字を認識/生成します。それが私が6バイト文字で意味したことです。Unixセマンティクスでは、1文字は1コードポイントです。あなたの複数のコードポイント「キャラクター」は、より一般的には、キャラクターから曖昧さをなくすためのグラフェンクラスターとして参照されます。
C
はデフォルトのロケールであり、「POSIX」は「C」のエイリアスです。「C」はANSI-Cから派生したと思います。たぶん、ANSI-Cは「POSIX」ロケールを定義しています。
C
ロケール名が「ANSI C」に由来することを意味するものではありません。
私が知る限り、OS XはUTF-8ロケールでコードポイントの照合順序を使用しているため、StéphaneChazelasの回答で言及されているポイントの一部は例外です。
OS Xでは26、Ubuntuでは310が印刷されます。
export LC_ALL=en_US.UTF-8
printf %b $(printf '\\U%08x\\n' $(seq $((0x11)) $((0x10ffff))))|grep -a '[a-z]'|wc -l
以下のコードは、OS Xでは何も印刷せず、入力がソートされていることを示しています。削除された6つのサロゲート文字により、不正なバイトシーケンスエラーが発生します。
export LC_ALL=en_US.UTF-8
for ((i=1;i<=0x1fffff;i++));do
x=$(printf %04x $i)
[[ $x = @(000a|d800|db7f|db80|dbff|dc00|dfff) ]]&&continue
printf %b \\U$x\\n
done|sort -c
以下のコードはOS Xで何も印刷しません。これは、同じ照合順序を持つ2つの連続したコードポイント(少なくともU + 000BとU + D7FFの間)がないことを示しています。
export LC_ALL=en_US.UTF-8
for ((i=0xb;i<=0xd7fe;i++));do
printf %b $(printf '\\U%08x\\n' $((i+1)) $i)|sort -c 2>/dev/null&&echo $i
done
(上記の例は、zshでエラーが発生する%b
ため使用printf \\U25
します。)
GNUシステムで同じ照合順序を持ついくつかの文字および文字シーケンスは、OS Xでは同じ照合順序を持ちません。これは、OS Xでは最初に(OS X sort
またはGNUを使用sort
)①、Ubuntuでは最初に印刷されます。
export LC_ALL=en_US.UTF-8;printf %s\\n ② ①|sort
OS Xでは3行(OS X sort
またはGNUを使用sort
)が印刷されますが、Ubuntuでは1行が印刷されます。
export LC_ALL=en_US.UTF-8;printf %b\\n \\u0d4c \\u0d57 \\u0d46\\u0d57|sort -u
xclock
warning(Missing charsets in String to FontSet conversion
)を使用LC_ALL=C.UTF-8
して問題を解決する場合は、キリル文字に関する問題を回避するために使用することをお勧めします。この環境変数を設定するには、~/.bashrc
ファイルの最後に次の行を追加する必要がありますexport LC_ALL=C.UTF-8