J'ai besoin d'un utilitaire internationalisé qui fait la même chose que tr
:obtient le caractère du flux et le remplace par un caractère correspondant.
Il ne s'agit pas d'une solution de cas particulier comme du bas vers le haut, mais une solution de cas général est nécessaire.
Sans gorillion canalisé sed
appels si possible.
Notez que tr
ne fonctionne pas sous Linux :il traduit des octets, pas des caractères. Cela échoue avec les encodages multi-octets.
$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ
Ņngstrom
Réponse acceptée :
GNU sed
fonctionne avec des caractères multi-octets. Donc :
$ echo 齯 | sed 'y/齯/ABŒ/'
ABŒ
Ce n'est pas tant que GNU tr
n'a pas été internationalisé mais qu'il ne prend pas en charge les caractères multi-octets (comme les caractères non ASCII dans les paramètres régionaux UTF-8). GNU tr
fonctionnerait avec Æ
, Œ
tant qu'ils étaient sur un seul octet comme dans le jeu de caractères iso8859-15.
Plus d'informations à ce sujet sur Comment rendre tr conscient des caractères non-ascii (unicode) ?
En tout cas, cela n'a rien à voir avec Linux, il s'agit du tr
implémentation sur le système. Si ce système utilise Linux comme noyau ou tr
est construit pour Linux ou utilise l'API du noyau Linux n'est pas pertinent car cette partie du tr
la fonctionnalité a lieu dans l'espace utilisateur.
boîte occupée tr
et GNU tr
sont les plus couramment trouvés sur les distributions de logiciels construits pour Linux et ne prennent pas en charge les caractères multi-octets, mais il y en a d'autres qui ont été portés sur Linux comme le tr
du coffre à outils d'héritage (porté depuis OpenSolaris) ou d'ast-open qui le font.
Notez que sed
est y
ne prend pas en charge les plages telles que a-z
. Notez également que si ce script qui contient sed 'y/齯/ABŒ/'
est écrit dans le jeu de caractères UTF-8, il ne fonctionnera plus comme prévu s'il est appelé dans une locale où UTF-8 n'est pas le jeu de caractères.
Une alternative pourrait être d'utiliser perl
:
perl -Mopen=locale -Mutf8 -pe 'y/a-z齯/A-ZABŒ/'
Ci-dessus, le code perl devrait être en UTF-8, mais il traitera l'entrée dans l'encodage de la locale (et la sortie dans ce même encodage). S'il est appelé dans une locale UTF-8, il translittèrera un Æ
UTF-8 (0xc3 0x86) en un Œ
UTF-8 (0xc5 0x92) et dans un ISO8859-15 pareil mais pour 0xc6 -> 0xbc.
Dans la plupart des shells, avoir ces caractères UTF-8 entre guillemets simples devrait être correct même si le script est appelé dans une locale où UTF-8 n'est pas le jeu de caractères (une exception est yash
qui se plaindrait si ces octets ne forment pas de caractères valides dans les paramètres régionaux). Cependant, si vous utilisez d'autres guillemets que des guillemets simples, cela pourrait causer des problèmes. Par exemple,
perl -Mopen=locale -Mutf8 -pe "y/♣`/&'/"
échouerait dans une locale où le jeu de caractères est BIG5-HKSCS car l'encodage de (0x5c) se trouve également être contenu dans d'autres caractères (comme
α
:0xa3 0x5c, et l'encodage UTF-8 de ♣
se termine par 0xa3).
Dans tous les cas, ne vous attendez pas à des choses comme
perl -Mopen=locale -Mutf8 -pe 'y/Á-Ź/A-Z/'
travailler à supprimer les accents aigus. Ce qui précède est en fait juste
perl -Mopen=locale -Mutf8 -pe 'y/x{c1}-x{179}/x{41}-x{5a}/'
Autrement dit, la plage est basée sur les points de code Unicode. Ainsi, les plages ne seront pas utiles en dehors de séquences très bien définies qui se trouvent dans le "bon ” ordre en Unicode comme A-Z
, 0-9
.
Si vous souhaitez supprimer les accents aigus, vous devrez utiliser des outils plus avancés tels que :
perl -Mopen=locale -MUnicode::Normalize -pe '
$_ = NFKD($_); s/x{301}//g; $_ = NFKC($_)'
C'est-à-dire utiliser les formes de normalisation Unicode pour décomposer les caractères, supprimer les accents aigus (ici la forme combinatoire U+0301
) et recomposer.
Un autre outil utile pour translittérer Unicode est uconv
de l'USI. Par exemple, ce qui précède pourrait également être écrit comme :
uconv -x '::NFKD; u0301>; ::NFKC;'
Cependant, cela ne fonctionnerait que sur les données UTF-8. Vous auriez besoin :
iconv -t utf-8 | uconv -x '::NFKD; u0301>; ::NFKC;' | iconv -f utf-8
Pour pouvoir traiter les données dans les paramètres régionaux de l'utilisateur.