Dans un shell : passer du texte en majuscules ou en minuscules
Je cherche un filtre qui passe en majuscules (ou en minuscules) toutes les lettres qu’il lit sur son entrée.
Sommaire
Avec tr
A priori, tr
semble fait pour ça :
$ echo 'majuscules' | tr a-z A-Z
MAJUSCULES
On peut aussi utiliser les classes de caractères POSIX :
$ echo 'MAJUSCULES' | tr [:upper:] [:lower:]
majuscules
Malheureusement, le tr
de GNU bute sur les signes diacritiques et les ligatures :
$ tr --version | head -n1
tr (GNU coreutils) 9.1
$ echo 'mæjùçcûlès' | tr a-z A-Z
MæJùçCûLèS
$ echo 'mæjùçcûlès' | tr [:lower:] [:upper:]
MæJùçCûLèS
Avec le tr
installé sur macOS (provenant apparemment de FreeBSD, si j’en crois le manuel), cela fonctionne, à condition d’utiliser les classes POSIX :
$ echo 'mæjùçcûlès' | tr a-z A-Z
MæJùçCûLèS
$ echo 'mæjùçcûlès' | tr [:lower:] [:upper:]
MÆJÙÇCÛLÈS
Avec sed
La version GNU de sed
(ci-après gsed
) propose une extension à la commande s
(voir la section 3.3 du manuel) :
- un
\U
placé dans le champ de remplacement passe en capitales tout ce qui suit ; - un
\L
passe en bas de casse tout ce qui suit.
On peut donc passer toute la ligne en majuscules avec la commande sed 's/.*/\U&/'
:
- dans le champ de recherche, l’expression régulière
.*
capture toute la ligne ; - dans le champ de remplacement, le caractère
&
subit une expansion et est remplacé par la chaîne capturée (en l’occurrence par toute la ligne) ; - mais comme on fait précéder le
&
d’un\U
, alors le texte de remplacement passe en capitales.
$ echo 'mæjùçcûlès' | gsed 's/.*/\U&/'
MÆJÙÇCÛLÈS
$ echo 'MÆJÙÇCÛLÈS' | gsed 's/.*/\L&/'
mæjùçcûlès
Au passage, la chaîne \E
annule l’effet de \U
ou \L
. On peut dès lors faire ce genre de choses :
$ echo 'MæJÙÇcÛLÈs' | sed 's/.*/\L& \E& \U&/'
mæjùçcûlès MæJÙÇcÛLÈs MÆJÙÇCÛLÈS
Un \u
ou \l
dans le champ de remplacement change seulement la casse du caractère qui le suit (j’utilise ici un _
plutôt qu’un /
pour séparer les différents champs de la commande passée à sed
) :
echo aBc | sed 's/a/\ua/ ; s/B/\lb/'
Abc
Le sed
de macOS ne propose pas ces extension à la norme POSIX :
$ echo 'mæjùçcûlès' | sed 's/.*/\U&/'
Umæjùçcûlès
Avec awk
Les fonctions toupper()
et tolower()
de awk
passent respectivement en capitales et en bas de casse la chaîne qu’on donne en argument.
Dans la version GNU de awk
(gawk
), cette fonction permet de changer la casse des caractères pourvus de diacritiques ainsi que des ligatures :
$ echo 'mæjùçcûlès' | gawk '{print toupper($0)}'
MÆJÙÇCÛLÈS
$ echo 'MÆJÙÇCÛLÈS' | gawk '{print tolower($0)}'
mæjùçcûlès
Attention : le awk installé par défaut sur Debian n’est pas celui de GNU mais mawk, avec lequel ça ne marche pas :
$ echo 'mæjùçcûlès' | mawk '{print toupper($0)}'
MæJùçCûLèS
$ echo 'MÆJÙÇCÛLÈS' | mawk '{print tolower($0)}'
mÆjÙÇcÛlÈs
Le awk
de GNU s’installe facilement (sudo apt install gawk
) ; une fois l’installation faite, la commande awk
lancera gawk
et non plus mawk
.
Le awk
installé par défaut sur macOS présente les mêmes limitations.
Conclusion
Si on est sur macOS :
- utiliser
tr
.
Sur Linux :
- utiliser
gsed
; - utiliser
gawk
.