Comment convertir des fichiers txt UTF-8 en majuscules en bash?


10

J'ai des fichiers .txt UTF-8 que je voudrais convertir en majuscules. Si c'était juste ASCII, je pourrais utiliser:

tr [:lower:] [:upper:]

Mais comme je travaille avec des signes diacritiques et d'autres choses, cela ne semble pas fonctionner. Je suppose que cela pourrait fonctionner si je définis les paramètres régionaux appropriés, mais j'ai besoin que ce script soit portable.

Réponses:


14

Tous:

tr '[:lower:]' '[:upper:]'

(ne pas oublier les guillemets, sinon que ne fonctionnera pas s'il y a un fichier appelé :, l... ou rdans le répertoire courant) ou:

awk '{print toupper($0)}'

ou:

dd conv=ucase

sont destinés à convertir les caractères en majuscules selon les règles définies dans les paramètres régionaux actuels. Cependant, même lorsque les paramètres régionaux utilisent UTF-8 comme jeu de caractères et définissent clairement la conversion de minuscules en majuscules, au moins GNU dd, GNU tret mawk(par défaut awksur Ubuntu par exemple) ne les suivent pas. En outre, il n'existe aucun moyen standard de spécifier des paramètres régionaux autres que Cou POSIX, donc si vous souhaitez convertir des fichiers UTF-8 en majuscules de manière portable indépendamment des paramètres régionaux actuels, vous n'avez pas de chance avec le toolchest standard.

Comme souvent, pour la portabilité, votre meilleur pari peut être perl:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

Maintenant, vous devez vous assurer que tout le monde n'est pas d'accord sur la version majuscule d'un caractère spécifique.

Par exemple, dans les locales turques, la majuscule in'est pas I, mais İ( <U0130>). Ici avec l'héritage toolchest trau lieu de GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
İÍ

Sur mon système, la perlconversion vers le haut est définie dans /usr/share/perl/5.14/unicore/To/Upper.pl, et je trouve qu'elle se comporte différemment sur quelques caractères de la libc GNU toupper()dans les C.UTF8paramètres régionaux par exemple, perlétant plus précise. Par exemple, perlconvertit correctement ɀ en Ɀ , contrairement à la libc GNU (2.17).


Pour ce que ça vaut, je travaille avec des lettres tchèques (et l'exemple que vous avez utilisé est en fait slovaque), où toutes les lettres majuscules sont clairement définies, mais l'ensemble de paramètres régionaux sera probablement C et non tchèque, c'est donc un problème. Perl est déjà utilisé dans cette chaîne d'outils, donc ajouter une autre utilisation n'est peut-être pas trop mauvais. Merci pour l'explication détaillée, btw!
VPeric

3

Je pense que vous pouvez le faire avec awket sa toupperfonction.

Par exemple

Ne fonctionne pas avec GNU tr:

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

Fonctionne avec GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ

@StephaneChazelas - merci j'ai changé l'exemple défaillant.
slm

Cela dépend des paramètres régionaux actuels et du tr ou la awkmise en œuvre. Par exemple, la plupart trconvertiront correctement les caractères dans un environnement local UTF8, selon l'environnement local actuel, GNU trne le fait pas. mawknon.
Stéphane Chazelas

1
En fait, sur FreeBSD (9.1), c'est l'inverse. Cela fonctionne avec tr, mais pas avecawk
Stéphane Chazelas

@StephaneChazelas - Je ne connais pas aussi bien les variances 8-). Quelqu'un vient de voter, demandez-vous pourquoi?
slm

2

Cela fonctionne avec OS X trmais pas avec GNU tr:

tr '[:lower:]' '[:upper:]'

Cela fonctionne avec gawkmais pas avec mawkou nawk(qui est /usr/bin/awksous OS X):

awk '{print toupper($0)}'

Une autre option consiste à utiliser GNU sed:

sed 's/./\u&/g'

Dans Bash 4.0 et versions ultérieures, vous pouvez également utiliser l' ^^extension des paramètres:

while IFS= read -r l;do printf %s\\n "${l^^}";done
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.