Unix benzeri sistemlerde bunun C
değeri nedir LC_ALL
?
Tüm yönler için aynı yerel ayarı zorladığını biliyorum ama ne yapar C
?
Unix benzeri sistemlerde bunun C
değeri nedir LC_ALL
?
Tüm yönler için aynı yerel ayarı zorladığını biliyorum ama ne yapar C
?
Yanıtlar:
Uygulamaları çıktı için varsayılan dili kullanmaya zorlar:
$ LC_ALL=es_ES man
¿Qué página de manual desea?
$ LC_ALL=C man
What manual page do you want?
ve byte bilge olmak için sıralama kuvvetleri:
$ 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
diğer yerelleştirme ayarlarını geçersiz kılan ortam değişkenidir ( bazı durumlar hariç$LANGUAGE
).
Yerelleştirmelerin farklı yönleri (bin ayırıcı veya ondalık nokta karakteri, karakter kümesi, sıralama düzeni, ay, gün adları, dil veya hata mesajları, para birimi simgesi gibi uygulama mesajları gibi) birkaç ortam değişkeni kullanılarak ayarlanabilir.
Genellikle $LANG
bölgenizi tanımlayan bir değere tercih edersiniz (örneğin fr_CH.UTF-8
, Fransızca konuşan İsviçre'de, UTF-8 kullanarak). Bireysel LC_xxx
değişkenler belirli bir yönü geçersiz kılar. LC_ALL
hepsini geçersiz kılar. locale
Argüman olmadan denilen komut, geçerli ayarların bir özetini verir.
Örneğin, bir GNU sisteminde, şunu alıyorum:
$ 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=
Örneğin tek bir ayarı geçersiz kılabilirim:
$ LC_TIME=fr_FR.UTF-8 date
jeudi 22 août 2013, 10:41:30 (UTC+0100)
Veya:
$ LC_MONETARY=fr_FR.UTF-8 locale currency_symbol
€
Veya LC_ALL ile herşeyi geçersiz kıl.
$ LC_ALL=C LANG=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8 cat /
cat: /: Is a directory
Bir komut dosyasında, belirli bir ayarı zorlamak istiyorsanız, kullanıcının hangi ayarları zorladığını bilmiyorsanız (muhtemelen LC_ALL), en iyi, en güvenli ve genellikle tek seçenek LC_ALL'ı zorlamaktır.
C
Yerel basit yerel olması gerekiyordu özel yerel bir. Ayrıca, diğer yerel ayarlar insanlar için olsa da, C yerel ayarının bilgisayarlar için olduğunu söyleyebiliriz. C yerelinde, karakterler tek bayttır, karakter kümesi ASCII'dir (buna gerek yoktur, ancak pratikte çoğumuzun kullanacağı sistemlerde olacaktır), sıralama düzeni bayt değerlerine dayanır, dil genellikle ABD İngilizcesidir (uygulama mesajları için (ay veya gün adları veya sistem kitaplıklarıyla ilgili mesajların aksine), uygulama yazarının takdirindedir) ve para birimi simgeleri gibi şeyler tanımlanmaz.
Bazı sistemlerde, örneğin ASCII dışı karakterler için sıralama düzeninin tanımlanmadığı POSIX yerel ayarlarında bir fark vardır.
Kullanıcı ayarlarının komut dosyanızı engellemesini önlemek için genellikle LC_ALL = C ile bir komut çalıştırırsınız. İsterseniz Örneğin, [a-z]
26 ASCII karakterleri eşleştirmek için a
için z
, ayarlamak zorunda LC_ALL=C
.
GNU sistemlerinde LC_ALL=C
ve LC_ALL=POSIX
(veya LC_MESSAGES=C|POSIX
) geçersiz kılmakla $LANGUAGE
, geçersiz kılıyorlardı LC_ALL=anything-else
.
Genellikle ayarlamanız gereken birkaç durum LC_ALL=C
:
sort -u
veya sort ... | uniq...
. C dışındaki birçok yerel yerde, bazı sistemlerde (özellikle GNU olanlar), bazı karakterler aynı sıralama düzenine sahiptir . sort -u
benzersiz satırlar bildirmiyor, ancak eşit sıralama düzenine sahip her satır grubundan biri. Bu nedenle, benzersiz satırlar istiyorsanız, karakterlerin bayt olduğu ve tüm karakterlerin farklı sıralama düzenine sahip olduğu bir C
yerel ayar gerekir ( yerel ayarın garanti ettiği).=
, POSIX uyumlu operatör expr
veya ==
POSIX uyumlu awk
s operatörü için geçerlidir ( mawk
ve gawk
bu konuda POSIX değildir).grep
. Kullanıcının dilinde bir harfle eşleşmek istiyorsan kullan grep '[[:alpha:]]'
ve değiştir LC_ALL
. Ancak a-zA-Z
ASCII karakterlerini eşleştirmek istiyorsanız , ya LC_ALL=C grep '[[:alpha:]]'
da LC_ALL=C grep '[a-zA-Z]'
¹ işaretine ihtiyacınız vardır . Önce ve [a-z]
sonra sıralanan karakterleri eşleştirir (birçok API'de ondan daha karmaşık olmasına rağmen). Diğer yerlerde, bunların ne olduğunu genellikle bilmiyorsunuz. Örneğin, bazı yerel ayarlar , kalıplar gibi bazı API'lerde ya da içerebilir, sıralama için büyük / küçük harfleri görmezden gelirler . Birçok UTF-8 yerellerde (dahil çoğu sistemlerde), latin harfleri içerecektir için aksan ile değil olanlar (bu yanaa
z
[a-z]
bash
[B-Z]
[A-Y]
en_US.UTF-8
[a-z]
a
y
z
z
Ben düşünemiyorum önlerinde türlü) dahil etmek isteyeyim neden (istediğini olurdu é
değil ź
?).kayan nokta aritmetiği ksh93
. ksh93
onur decimal_point
ayarı LC_NUMERIC
. İçeren bir komut dosyası yazarsanız a=$((1.2/7))
, yerel ayarı ondalık ayırıcı olarak virgülleri olan bir kullanıcı tarafından çalıştırıldığında çalışmayı durdurur:
$ 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
O zaman şöyle bir şeye ihtiyacın var:
#! /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
Bir yandan not: ,
Ondalık ayırıcı, ,
daha da fazla karışıklığa neden olabilecek aritmetik operatörle çakışır.
grep '<.*>'
bir içeren hatları aramaya <
, >
çifti mısın UTF-8 yerel ayarda konum ve giriş iso8859-15 gibi ayarlanmış bir tek bayt 8 bit karakter kodlanmış olması durumunda hiçbir iş. Bunun nedeni .
, iso8859-15'deki yalnızca karakterlerle ASCII olmayan karakterlerin eşleşmesi UTF-8'de geçerli bir karakter oluşturmamasıdır. Öte yandan, LC_ALL=C grep '<.*>'
herhangi bir bayt değeri C
yerel olarak geçerli bir karakter oluşturduğu için çalışacaktır .Giriş verilerini işlediğiniz veya bir insan için / amaçlanmayan çıktı verilerini işlediğiniz zaman. Bir kullanıcıyla konuşuyorsanız, kongre ve dillerini kullanmak isteyebilirsiniz, ancak örneğin, İngiliz tarzı ondalık basamağı bekleyen başka bir uygulamayı beslemek için bazı numaralar oluşturursanız veya İngilizce ay adlarını kullanırsanız, LC_ALL = C'yi ayarla:
$ 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
Bu da (olduğu gibi harf duyarsız karşılaştırma gibi şeyler için de geçerlidir grep -i
) ve vaka dönüşüm ( awk
'ın toupper()
, dd conv=ucase
...). Örneğin:
grep -i i
I
kullanıcının yerel ayarlarında eşleşme garantisi yoktur . Örneğin bazı Türk lokallerinde, orada büyük harf i
olduğu İ
(noktaya dikkat etmeyin ) ve küçük harf I
olduğu gibi ı
(eksik noktayı not edin).
¹ Metnin kodlamasına bağlı olarak, mutlaka yapılması gereken doğru bir şey yoktur. Bu UTF-8 veya tek baytlık karakter kümeleri için geçerlidir (iso-8859-1 gibi), ancak UTF-8 olmayan çok baytlı karakter kümeleri için geçerli değildir.
Örneğin, bir zh_HK.big5hkscs
yerel ayardaysanız (Hong Kong, BIG5 Çince karakter kodlamasının Hong Kong varyantını kullanarak) ve bu karakter gruplarında kodlanmış bir dosyada İngilizce harfleri aramak istiyorsanız, aşağıdakilerden birini yapın:
LC_ALL=C grep '[[:alpha:]]'
veya
LC_ALL=C grep '[a-zA-Z]'
yanlış olurdu, çünkü o karakter dizisinde (ve diğerleri ancak UTF-8'in ortaya çıkmasından bu yana pek kullanılmıyordu), A-Za-z karakterlerinin ASCII kodlamasına karşılık gelen baytlar içeriyordu . Örneğin, tümü A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
(ve daha pek çoğu), kodlamasını içerir A
. 䨝
0x96 0x41 ve A
0x41 ASCII'deki gibidir. Böylece LC_ALL=C grep '[a-zA-Z]'
, bu karakterleri içeren satırlarda, bu bayt dizilerini yanlış yorumlayacağı için eşleştireceğiz.
LC_COLLATE=C grep '[A-Za-z]'
işe yarayacaktı, ancak yalnızca LC_ALL
başka türlü ayarlanmadığında (bu geçersiz kılacaktı LC_COLLATE
). Yani yapmak zorunda kalabilirsin:
grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'
Yerel kodlamada kodlanmış bir dosyada İngilizce harfleri aramak istiyorsanız.
C
Yerel ayar yalnızca "taşınabilir karakter setini" (ASCII 0-127) desteklemek için gereklidir ve karakter> 127 için davranış teknik olarak belirtilmez . Uygulamada, çoğu program onlara opak veri olarak davranacak ve tanımladığınız şekilde iletecektir. Ancak hepsi değil: özellikle, Ruby C
yerel ayarlarda çalışıyorsa bayt> 127 baytlık char verilerini boğabilir. Gerçekten teknik olarak "uygun" olup olmadığını bilmiyorum, ama vahşi doğada gördük .
perl
s' \x{7FFFFFFFFFFFFFFF}
Unicode kod noktalarına aralığı keyfi U +, 10FFFF değerinden ile sınırlı iken) ve (UTF-16 tasarım sınırlaması nedeniyle), bazı araçlar hala 6 bayt karakterleri tanıyor / üretiyor. Bunu 6 byte karakterle kastettim. Unix anlamında, bir karakter bir kod noktasıdır. Sizin birden fazla kod noktası "karakterler" daha genel karakterlerinden belirsizliği giderecek graphem kümeleri gibi başvurulur.
C
varsayılan yerel ayardır, "POSIX", "C" nin diğer adıdır. Sanırım "C", ANSI-C'den türetilmiş. Belki ANSI-C "POSIX" yerel ayarını tanımlar.
C
yerel ayar adının "ANSI C" den geldiği anlamına gelmez .
Söyleyebileceğim kadarıyla, OS X UTF-8 yerel ayarlarında kod noktası harmanlama sırasını kullanıyor, bu yüzden Stéphane Chazelas'ın cevabında belirtilen noktaların bir istisnası.
Bu, OS X'te 26 ve Ubuntu'da 310 yazdırır:
export LC_ALL=en_US.UTF-8
printf %b $(printf '\\U%08x\\n' $(seq $((0x11)) $((0x10ffff))))|grep -a '[a-z]'|wc -l
Aşağıdaki kod, girişin sıralandığını gösteren OS X'te hiçbir şey yazdırmaz. Kaldırılan altı yedek karakter, geçersiz bir bayt dizisi hatasına neden oluyor.
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
Aşağıdaki kod, OS X'te hiçbir şeyi yazdırmaz; bu, aynı harmanlama sırasına sahip iki ardışık kod noktasının (en azından U + 000B ve U + D7FF arasında) olmadığını gösterir.
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
(Yukarıdaki örnekler, %b
çünkü printf \\U25
zsh'da bir hatayla sonuçlandığından kullanılır .)
GNU sistemlerinde aynı harmanlama düzeni var karakterlerden bazıları karakterler ve diziler aynı harmanlama Bu baskılar (OS X olduğunu kullanılarak OS X ilk ① OS X sırasını yok sort
ya da GNU'ya sort
) ama ② ilk Ubuntu:
export LC_ALL=en_US.UTF-8;printf %s\\n ② ①|sort
Bu, OS X’te üç satır yazdırır (OS X’ler sort
veya GNU’yu kullanarak sort
) ancak bir satır Ubuntu’da:
export LC_ALL=en_US.UTF-8;printf %b\\n \\u0d4c \\u0d57 \\u0d46\\u0d57|sort -u
Görünüşe LC_COLLATE
göre ls tarafından kullanılan "alfabetik sıra" da kontrol ediliyor. ABD yerel ayarı şu şekilde sıralanacaktır:
a.C
aFilename.C
aFilename.H
a.H
temelde dönemleri görmezden geliyor. Tercih edebilirsiniz:
a.C
a.H
aFilename.C
aFilename.H
Kesinlikle yaparım. Bunu başarmak LC_COLLATE
için ayar C
. Tüm harflerden sonra küçük harfleri de sıralayacağını unutmayın:
A.C
A.H
AFilename.C
a.C
a.H
xclock
Uyarı (Missing charsets in String to FontSet conversion
) ile ilgili bir sorunu çözmek istiyorsanızLC_ALL=C.UTF-8
, kiril ile ilgili sorunları önlemek için kullanacaksanız daha iyi olacaktır . Bu ortam değişkenini ayarlamak için~/.bashrc
dosyanın sonuna şu satırı eklemelisiniz -export LC_ALL=C.UTF-8