$ locale charmap
UTF-8
Dans mon environnement actuel, le jeu de caractères est UTF-8, c'est-à-dire que les caractères sont codés avec 1 à 4 octets par caractère (bien que parce que la définition d'origine de UTF-8 permette le code de caractère jusqu'à 0x7fffffff, la plupart des outils reconnaissent UTF- Séquences de 8 octets jusqu'à 6 octets).
Dans ce jeu de caractères, tous les caractères d'Unicode sont disponibles, a a
est codé comme valeur d'octet 65, a 乕
comme 3 octets 228 185 149 et é
comme séquence de deux octets 195 169 par exemple.
$ printf 乕 | wc -mc
1 3
$ printf a | wc -mc
1 1
À présent:
$ export fr_FR.iso885915@euro
$ locale charmap
ISO-8859-15
J'ai modifié mon environnement, où le jeu de caractères est désormais ISO-8859-15 (d'autres choses comme la langue, le symbole monétaire, le format de date ont également été modifiés, la collection de ces paramètres régionaux étant appelée locale ). J'ai besoin de démarrer un nouvel émulateur de terminal dans cet environnement pour qu'il puisse adapter son rendu de caractère aux nouveaux paramètres régionaux.
ISO-8859-15 est un jeu de caractères à un octet, ce qui signifie qu'il n'a que 256 caractères (en fait encore moins que ceux qui sont réellement couverts). Ce jeu de caractères particulier est utilisé pour les langues d'Europe occidentale car il couvre la plupart de ses langues (et le symbole de l'euro).
Il a le a
caractère avec la valeur d'octet 65 comme en UTF-8 ou ASCII, il a également le é
caractère (comme couramment utilisé en français ou en espagnol par exemple) mais avec la valeur d'octet 233, il n'a pas le caractère 乕.
Dans cet environnement, wc -c
et wc -m
donnera toujours le même résultat.
Dans Ubuntu, comme sur la plupart des systèmes modernes de type Unix, la valeur par défaut est généralement UTF-8 car c'est le seul jeu de caractères (et codage) pris en charge qui couvre toute la plage Unicode.
Il existe d'autres encodages de caractères multi-octets, mais ils ne sont pas aussi bien pris en charge sur Ubuntu et vous devez passer par des cercles pour pouvoir générer un environnement local avec ceux-ci, et si vous le faites, vous constaterez que beaucoup de choses ne le font pas travaille correctement.
Donc, en effet sur Ubuntu, les jeux de caractères sont soit à un octet, soit UTF-8.
Maintenant, quelques notes supplémentaires:
En UTF-8, toutes les séquences d'octets ne forment pas des caractères valides. Par exemple, tous les caractères UTF-8 qui ne sont pas des caractères ASCII sont formés avec des octets qui ont tous le 8e bit, mais où seul le premier a le 7e bit.
Si vous avez une séquence d'octets avec le 8ème bit défini, dont aucun n'a le 7ème bit, alors cela ne peut pas être traduit en caractère. Et c'est là que vous commencez à avoir des problèmes et des incohérences car les logiciels ne savent pas quoi en faire. Par exemple:
$ printf '\200\200\200' | wc -mc
0 3
$ printf '\200\200\200' | grep -q . || echo no
no
wc
et grep
n'y trouver aucun personnage mais:
$ x=$'\200\200\200' bash -c 'echo "${#x}"'
3
bash
trouve 3. Lorsqu'il ne peut pas mapper une séquence d'octets à un caractère, il considère chaque octet comme un caractère.
Cela peut devenir encore plus compliqué car il y a des points de code dans Unicode qui ne sont pas valides en tant que caractères, et certains qui ne sont pas des caractères , et selon l'outil, leur codage UTF-8 peut ou non être considéré comme un caractère.
Une autre chose à prendre en considération est la différence entre le caractère et le graphem, et la façon dont ils sont rendus.
$ printf 'e\u301\u20dd\n'
é⃝
$ printf 'e\u301\u20dd' | wc -mc
3 6
Là, nous avons codé 3 caractères sous forme de 6 octets rendus sous la forme d'un graphem, car nous avons 3 caractères combinés ensemble (un caractère de base, un accent aigu combinant et un cercle englobant combinant).
L'implémentation GNU de wc
comme trouvée sur Ubuntu a un -L
commutateur pour vous indiquer la largeur d'affichage de la ligne la plus large dans l'entrée:
$ printf 'e\u301\u20dd\n' | wc -L
1
Vous constaterez également que certains caractères occupent 2 cellules dans ce calcul de largeur comme notre 乕
caractère ci-dessus:
$ echo 乕 | wc -L
2
En conclusion: dans le mot le plus sauvage, l'octet, le caractère et le graphem ne sont pas nécessairement les mêmes.