Quelle est la C
valeur pour LC_ALL
les systèmes de type Unix?
Je sais que cela force le même lieu pour tous les aspects mais que fait C
-on?
Quelle est la C
valeur pour LC_ALL
les systèmes de type Unix?
Je sais que cela force le même lieu pour tous les aspects mais que fait C
-on?
Réponses:
Il oblige les applications à utiliser la langue par défaut pour la sortie:
$ LC_ALL=es_ES man
¿Qué página de manual desea?
$ LC_ALL=C man
What manual page do you want?
et les forces de tri pour être en octets:
$ 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
est la variable d'environnement qui remplace tous les autres paramètres de localisation ( sauf $LANGUAGE
dans certaines circonstances ).
Différents aspects des localisations (comme le séparateur de milliers ou le point, le jeu de caractères, l'ordre de tri, les noms de mois et de jour, la langue ou les messages d'application tels que les messages d'erreur, le symbole monétaire) peuvent être définis à l'aide de quelques variables d'environnement.
Vous définissez généralement $LANG
vos préférences avec une valeur identifiant votre région (par exemple, fr_CH.UTF-8
si vous êtes en Suisse romande et utilisez UTF-8). Les LC_xxx
variables individuelles remplacent un certain aspect. LC_ALL
les remplace tous. La locale
commande, lorsqu'elle est appelée sans argument, donne un résumé des paramètres actuels.
Par exemple, sur un système GNU, je reçois:
$ 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=
Je peux remplacer un paramètre individuel avec par exemple:
$ LC_TIME=fr_FR.UTF-8 date
jeudi 22 août 2013, 10:41:30 (UTC+0100)
Ou:
$ LC_MONETARY=fr_FR.UTF-8 locale currency_symbol
€
Ou remplacez tout avec LC_ALL.
$ LC_ALL=C LANG=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8 cat /
cat: /: Is a directory
Dans un script, si vous souhaitez forcer un paramètre spécifique, car vous ne savez pas quels paramètres l'utilisateur a forcé (éventuellement également LC_ALL), votre meilleure option, généralement la plus sûre et la plus courante, consiste à forcer LC_ALL.
La C
locale est une locale spéciale censée être la locale la plus simple. Vous pouvez également dire que, tandis que les autres paramètres régionaux sont destinés aux humains, les paramètres régionaux C sont destinés aux ordinateurs. Dans les paramètres régionaux C, les caractères sont des octets simples, le jeu de caractères est ASCII (eh bien, ce n’est pas une obligation, mais sera en pratique dans les systèmes que la plupart d’entre nous ne pourront jamais utiliser), l’ordre de tri est basé sur les valeurs des octets, la langue est généralement l'anglais américain (bien que pour les messages d'application (par opposition à des noms tels que les noms de mois ou de jours ou les messages des bibliothèques système), c'est à la discrétion de l'auteur de l'application) et des éléments tels que les symboles monétaires ne sont pas définis.
Sur certains systèmes, il existe une différence avec les paramètres régionaux POSIX où, par exemple, l'ordre de tri des caractères non-ASCII n'est pas défini.
Vous exécutez généralement une commande avec LC_ALL = C pour éviter que les paramètres de l'utilisateur n'interfèrent avec votre script. Par exemple, si vous souhaitez [a-z]
faire correspondre les 26 caractères ASCII de a
à z
, vous devez définir LC_ALL=C
.
Sur les systèmes GNU, LC_ALL=C
et LC_ALL=POSIX
(ou LC_MESSAGES=C|POSIX
) remplacer $LANGUAGE
, alors LC_ALL=anything-else
que non.
Quelques cas où vous devez généralement définir LC_ALL=C
:
sort -u
ou sort ... | uniq...
. Dans de nombreux environnements locaux autres que C, sur certains systèmes (notamment ceux de GNU), certains caractères ont le même ordre de tri . sort -u
ne rapporte pas de lignes uniques, mais une de chaque groupe de lignes ayant un ordre de tri égal. Donc, si vous voulez des lignes uniques, vous avez besoin d'une locale où les caractères sont exprimés en octets et où tous les caractères ont un ordre de tri différent (ce que la C
locale garantit).=
opérateur de POSIX conforme expr
ou celui ==
de POSIX conforme awk
( mawk
et gawk
ne sont pas POSIX à cet égard), qui ne vérifie pas si deux chaînes sont identiques, mais si elles se trient de la même manière.grep
. Si vous voulez faire correspondre une lettre dans la langue de l'utilisateur, utilisez grep '[[:alpha:]]'
et ne modifiez pas LC_ALL
. Mais si vous souhaitez faire correspondre les a-zA-Z
caractères ASCII, vous avez besoin de LC_ALL=C grep '[[:alpha:]]'
ou LC_ALL=C grep '[a-zA-Z]'
¹. [a-z]
correspond aux caractères triés a
avant et après z
(bien qu'avec de nombreuses API, c'est plus compliqué que cela). Dans d'autres endroits, vous ne savez généralement pas ce que c'est. Par exemple, certains paramètres régionaux ignorent la casse pour le tri. Par conséquent, [a-z]
dans certaines API telles que les bash
modèles, ils peuvent inclure [B-Z]
ou [A-Y]
. Dans beaucoup de locales UTF-8 (y compris en_US.UTF-8
sur la plupart des systèmes), [a-z]
inclura les lettres latines de a
à y
avec des signes diacritiques mais pas celles de z
(depuisz
que je ne peux pas imaginer serait ce que vous voulez (pourquoi voudriez-vous inclure é
et non ź
?).arithmétique en virgule flottante ksh93
. ksh93
honore la decimal_point
mise en LC_NUMERIC
. Si vous écrivez un script qui contient a=$((1.2/7))
, il ne fonctionnera plus s'il est exécuté par un utilisateur dont les paramètres régionaux ont une virgule comme séparateur décimal:
$ 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
Ensuite, vous avez besoin de choses comme:
#! /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
En remarque: le ,
séparateur décimal est en conflit avec l' ,
opérateur arithmétique, ce qui peut causer encore plus de confusion.
grep '<.*>'
pour rechercher les lignes contenant une <
, >
deux ne fonctionnera si vous êtes dans un lieu UTF-8 et l'entrée est codée dans un seul octet caractère 8 bits , comme iso8859-15. En effet, .
seules les correspondances et les caractères non-ASCII de l'iso8859-15 risquent de ne pas former un caractère valide dans UTF-8. D'autre part, LC_ALL=C grep '<.*>'
cela fonctionnera car toute valeur d'octet forme un caractère valide dans les C
paramètres régionaux.Chaque fois que vous traitez des données d'entrée ou des données de sortie non destinées à / par un humain. Si vous parlez à un utilisateur, vous voudrez peut-être utiliser sa convention et sa langue, mais par exemple, si vous générez des nombres pour alimenter une autre application qui attend des points décimaux de style anglais, ou des noms de mois en anglais, vous souhaiterez: set 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
Cela s'applique également à des choses comme la comparaison sans distinction de casse (comme dans grep -i
) et la conversion de casse ( awk
's toupper()
, dd conv=ucase
...). Par exemple:
grep -i i
ne correspond pas forcément aux I
paramètres régionaux de l'utilisateur. Dans certains endroits turcs par exemple, elle ne précise pas en majuscules i
est İ
(notez le point) et il en minuscules I
est ı
(notez le point manquant).
¹ En fonction du codage du texte, ce n’est pas nécessairement la bonne chose à faire. Ceci est valable pour les jeux de caractères UTF-8 ou mono-octets (comme l'iso-8859-1), mais pas nécessairement pour les jeux de caractères multi-octets non UTF-8.
Par exemple, si vous vous trouvez dans un zh_HK.big5hkscs
environnement local (Hong Kong, en utilisant la variante hongkongaise du codage de caractères chinois BIG5) et que vous souhaitez rechercher des lettres anglaises dans un fichier codé dans ce jeu de caractères, effectuez l'une des opérations suivantes:
LC_ALL=C grep '[[:alpha:]]'
ou
LC_ALL=C grep '[a-zA-Z]'
aurait tort, car dans ce jeu de caractères (et de nombreux autres, mais à peine utilisés depuis l'apparition de UTF-8), de nombreux caractères contiennent des octets correspondant au codage ASCII des caractères A-Za-z. Par exemple, tous A䨝䰲丕乙乜你再劀劈呸哻唥唧噀噦嚳坽
(et beaucoup d’autres) contiennent le codage de A
. 䨝
est 0x96 0x41 et A
est 0x41 comme en ASCII. Donc, nos LC_ALL=C grep '[a-zA-Z]'
correspondraient sur les lignes contenant ces caractères, car cela interpréterait mal ces séquences d'octets.
LC_COLLATE=C grep '[A-Za-z]'
fonctionnerait, mais seulement si LC_ALL
n'est pas défini autrement (ce qui écraserait LC_COLLATE
). Donc, vous pourriez avoir à faire:
grep '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]'
si vous voulez rechercher des lettres anglaises dans un fichier codé dans le codage des paramètres régionaux.
C
paramètres régionaux sont requis uniquement pour prendre en charge le "jeu de caractères portable" (ASCII 0-127), et le comportement des caractères supérieurs à 127 est techniquement non spécifié . En pratique, la plupart des programmes les traiteront comme des données opaques et les transmettront comme vous l'avez décrit. Mais pas tous: en particulier, Ruby peut s’étouffer avec des données char avec des octets> 127 s’il s’exécute dans les C
paramètres régionaux. Honnêtement, je ne sais pas si c'est techniquement "conforme", mais nous l'avons vu à l'état sauvage .
perl
« s \x{7FFFFFFFFFFFFFFF}
) et tandis que la gamme de points de code Unicode a été arbitrairement limitée à U + 10FFFF (en raison de la limitation de conception UTF-16), certains outils reconnaissent / produisent toujours des caractères de 6 octets. C'est ce que je voulais dire par 6 caractères sur 12 octets. Dans la sémantique Unix, un caractère est un point de code. Vos plus d'un codepoint « caractères » sont plus généralement référencés comme des grappes de GRAPHEM désambiguïser de caractères.
C
est la langue par défaut, "POSIX" est l'alias de "C". Je suppose que "C" est dérivé de ANSI-C. Peut-être que ANSI-C définit les paramètres régionaux "POSIX".
C
nom de la locale dérive de "ANSI C".
Autant que je sache, OS X utilise l'ordre de classement des points de code dans les paramètres régionaux UTF-8. Il s'agit donc d'une exception à certains points mentionnés dans la réponse de Stéphane Chazelas.
Cela imprime 26 sous OS X et 310 sous Ubuntu:
export LC_ALL=en_US.UTF-8
printf %b $(printf '\\U%08x\\n' $(seq $((0x11)) $((0x10ffff))))|grep -a '[a-z]'|wc -l
Le code ci-dessous n’imprime rien dans OS X, ce qui indique que l’entrée est triée. Les six caractères de substitution qui sont supprimés provoquent une erreur de séquence d'octets non conforme.
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
Le code ci-dessous n'imprime rien dans OS X, indiquant qu'il n'y a pas deux points de code consécutifs (au moins entre U + 000B et U + D7FF) qui ont le même ordre de classement.
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
(Les exemples ci-dessus utilisent %b
car il en printf \\U25
résulte une erreur dans zsh.)
Certains caractères et séquences de caractères qui ont le même ordre de classement dans les systèmes GNU n'ont pas le même ordre de classement dans OS X. Ceci affiche ① en premier dans OS X (avec OS X sort
ou GNU sort
), mais en d'abord dans Ubuntu:
export LC_ALL=en_US.UTF-8;printf %s\\n ② ①|sort
Ceci affiche trois lignes sous OS X (avec OS X sort
ou GNU sort
) mais une ligne sous Ubuntu:
export LC_ALL=en_US.UTF-8;printf %b\\n \\u0d4c \\u0d57 \\u0d46\\u0d57|sort -u
Il semble que cela LC_COLLATE
contrôle "l'ordre alphabétique" utilisé par ls. Les paramètres régionaux américains seront triés comme suit:
a.C
aFilename.C
aFilename.H
a.H
en ignorant fondamentalement les périodes. Vous pourriez préférer:
a.C
a.H
aFilename.C
aFilename.H
Je fais certainement. Paramétrer LC_COLLATE
pour C
accomplir ceci. Notez qu'il va également trier les minuscules après toutes les capitales:
A.C
A.H
AFilename.C
a.C
a.H
xclock
warning (Missing charsets in String to FontSet conversion
), il sera préférableLC_ALL=C.UTF-8
d’éviter les problèmes avec cyrillic. Pour définir cette variable d’environnement, vous devez ajouter la ligne suivante à la fin du~/.bashrc
fichier -export LC_ALL=C.UTF-8