UnixライクなシステムでLC_ALL
のC
値は何をしますか?
私はそれがすべての面で同じロケールを強制することを知っていますが、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
_を除く )。
いくつかの環境変数を使用して、ローカリゼーションのさまざまな側面(1,000区切り記号または小数点文字、文字セット、並べ替え順序、月、曜日の名前、言語またはアプリケーションメッセージ(エラーメッセージ、通貨記号など))を設定できます。
通常、_$LANG
_は、地域を識別する値(UTF-8を使用してフランス語圏のスイスにいる場合は_fr_CH.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]
_をa
からz
までの26個のASCII文字に一致させるには、_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 ones))では、 一部の文字は同じ並べ替え順を持っています です。_sort -u
_は一意を報告しません行ですが、並べ替え順序が等しい行の各グループの1つです。したがって、一意の行が必要な場合は、文字がバイトで、すべての文字が異なる並べ替え順序を持つロケールが必要です(C
ロケールはこれを保証します)。 。=
_演算子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]
_は、並べ替え後の文字に一致しますa
以前z
(ただし、多くのAPIを使用すると、それよりも複雑になります)。他のロケールでは、通常、それらが何であるかがわかりません。たとえば、一部のロケールでは、並べ替えの大文字と小文字を区別しません_[a-z]
_ bash
パターンなどの一部のAPIでは、_[B-Z]
_または_[A-Y]
_を含めることができます。多くのUTF-8ロケール(ほとんどのシステムの_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 '<.*>'
_、_<
_のペアを含む行を検索するインスタンス_>
_は、UTF-8ロケールで、入力がシングルバイトの8ビットでエンコードされている場合は機能しませんiso8859-15のような文字セットです。これは、_.
_が文字にのみ一致し、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
は_ı
_(ドットがないことに注意してください)。
theただし、テキストのエンコードによっては、必ずしも正しいこととは限りません。これは、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が登場して以来ほとんど使用されていません)では、対応する多くの文字containバイトが含まれるため、誤りですASCII A-Za-z文字のエンコーディング。たとえば、_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
はデフォルトのロケールで、「POSIX」は「C」のエイリアスです。 "C"はANSI-Cに由来すると思います。たぶんANSI-Cは "POSIX"ロケールを定義しています。
私の知る限り、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
(上記の例では%b
理由はprintf \\U25
はzshでエラーになります。)
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
LC_COLLATE
は、lsによって使用される「アルファベット順」も制御します。 USロケールは次のようにソートされます。
a.C
aFilename.C
aFilename.H
a.H
基本的に期間を無視します。あなたが好むかもしれません:
a.C
a.H
aFilename.C
aFilename.H
私は確かにそうします。設定LC_COLLATE
to C
はこれを実現します。また、すべての大文字の後に小文字で並べ替えます。
A.C
A.H
AFilename.C
a.C
a.H