Convertir tout le texte des majuscules en minuscules et vice versa?
17
Ma question est de savoir comment convertir tout le texte des majuscules en minuscules et vice versa? C'est changer les cas de toutes les lettres. Cela doit être fait avec un sedremplacement en quelque sorte.
$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy
ou d'une manière plus courte avec GNU sed, en travaillant avec n'importe quel caractère pour lequel une conversion en minuscules <-> majuscules existe dans votre environnement local:
$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy
Votre deuxième suppose un GNU sedet un cas alternatif dans l'entrée. Utilisez à la sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'place (toujours spécifique à GNU). La première convertit uniquement les 26 lettres latines ASCII, tandis que la seconde convertit toute lettre reconnue comme telle par votre environnement local. L' trun n'a de sens que dans les paramètres régionaux ASCII. Celui perlne fonctionne que pour les lettres latines ASCII.
Stéphane Chazelas
16
POSIX, cela ne peut pas être fait sedsauf en fournissant l'ensemble complet de lettres que vous souhaitez translittérer comme l' a montré @cuonglm .
Cela pourrait être fait avec tr, et c'est à cela que trsert (translittération):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
Cependant, sous Linux, il a des limites. Sur les 3 trimplémentations couramment trouvées sur les systèmes Linux:
avec GNU tr, qui ne fonctionne que pour les jeux de caractères à un octet. Par exemple, Stéphane Chazelasdans les locales UTF-8, cela donne à la sTéPHANE cHAZELASplace de sTÉPHANE cHAZELAS. C'est une limitation connue de GNU tr.
avec trde l'héritage toolchest, cela ne fonctionne pas (vous obtenez stéphane chazelas).
Ce n'est pas le genre de chose que busybox trfera.
Sur FreeBSD, cela fonctionne bien. Vous vous attendriez à ce que cela fonctionne également dans les systèmes Unix certifiés.
Donc, dans le monde du bureau, seul OSX le fait? Pourquoi ça ne marche pas? S'agit-il simplement des différentes implémentations, car il semble qu'il y ait un décalage constant dans la valeur hexadécimale entre la version minuscule du caractère accentué et son homologue majuscule?
1
@ illuminÉ, vous ne savez pas ce que vous entendez par monde de bureau . AFAICS, le problème est avec GNU, la plupart des Unices ont des "bureaux". Mis à part ASCII et certains jeux de caractères iso8859, je ne suis pas conscient que vous pouvez généraliser le décalage hexadécimal, et cela n'aurait aucun sens avec des encodages comme UTF-8. Par exemple, en UTF-8, majuscule ⴠ(e2 b4 a0) est Ⴠ(e1 83 80); deux i(69) et ı(c4 b1) ont I(49) en majuscules (sauf dans des endroits où la Turquie idevient İ). La raison pour laquelle cela ne fonctionne pas avec GNU trest que GNU trfonctionne avec des octets et non avec des caractères.
Stéphane Chazelas
Je voulais dire du courant dominant, mais cela n'a pas vraiment de sens, alors merci pour la tête. Je viens de regarder les caractères accentués français (et vraiment juste "é") et j'ai fait des hypothèses très simplistes, oubliant encore qu'il s'agit d'octets. Mais l'héritage? Je vais relire cette réponse!
1
@ illuminÉ, pour heirloom, c'est un problème différent, il semble qu'il ne supporte qu'une seule occurrence de [:lower:]or [:upper:](donc la première est ignorée). Même en français, œ -> Œest c5 93 -> c5 92en UTF-8 et bd -> bcen iso8859-15.
Stéphane Chazelas
2
Bien que cela ait les mêmes limites déjà mentionnées que la trsolution proposée par Stéphane Chazelas, c'est une autre façon de le faire:
Je larguer stderren /dev/nulllà parce que ddfournit également des statistiques de toutes ses opérations sur le 2descripteur de fichier. Cela peut être utile selon ce que vous faites, mais ce n'était pas le cas pour cette démonstration. Toutes les autres choses que vous pouvez faire dds'appliquent toujours, par exemple:
Cependant, il n'échange pas le cas (car in aBcn'est pas converti en AbC).
Stéphane Chazelas
1
@ StéphaneChazelas - c'est vrai, mais à moins que j'aie mal compris, ce n'était pas la question, n'est-ce pas?
mikeserv
2
Si votre objectif principal est de convertir un fichier de classe inférieure en classe supérieure, pourquoi ne l'utilisez-vous pas tret STDOUTpour convertir votre fichier:
$cat FILENAME | tr a-z A-Z > FILENAME2
Où se FILENAMEtrouve votre fichier d'origine. Où se FILENAME2trouve votre fichier de sortie converti.
tr
serait plus approprié quesed
.Réponses:
Voici une façon simple de
sed
:ou d'une manière plus courte avec GNU
sed
, en travaillant avec n'importe quel caractère pour lequel une conversion en minuscules <-> majuscules existe dans votre environnement local:si vous pouvez utiliser un autre outil, comme:
perl
(limité aux lettres ASCII):perl
(plus généralement):la source
sed
et un cas alternatif dans l'entrée. Utilisez à lased -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
place (toujours spécifique à GNU). La première convertit uniquement les 26 lettres latines ASCII, tandis que la seconde convertit toute lettre reconnue comme telle par votre environnement local. L'tr
un n'a de sens que dans les paramètres régionaux ASCII. Celuiperl
ne fonctionne que pour les lettres latines ASCII.POSIX, cela ne peut pas être fait
sed
sauf en fournissant l'ensemble complet de lettres que vous souhaitez translittérer comme l' a montré @cuonglm .Cela pourrait être fait avec
tr
, et c'est à cela quetr
sert (translittération):Cependant, sous Linux, il a des limites. Sur les 3
tr
implémentations couramment trouvées sur les systèmes Linux:tr
, qui ne fonctionne que pour les jeux de caractères à un octet. Par exemple,Stéphane Chazelas
dans les locales UTF-8, cela donne à lasTéPHANE cHAZELAS
place desTÉPHANE cHAZELAS
. C'est une limitation connue de GNUtr
.tr
de l'héritage toolchest, cela ne fonctionne pas (vous obtenezstéphane chazelas
).tr
fera.Sur FreeBSD, cela fonctionne bien. Vous vous attendriez à ce que cela fonctionne également dans les systèmes Unix certifiés.
Le
bash
shell a un opérateur dédié pour cela:Avec
zsh -o extendedglob
:la source
ⴠ
(e2 b4 a0) estჀ
(e1 83 80); deuxi
(69) etı
(c4 b1) ontI
(49) en majuscules (sauf dans des endroits où la Turquiei
devientİ
). La raison pour laquelle cela ne fonctionne pas avec GNUtr
est que GNUtr
fonctionne avec des octets et non avec des caractères.[:lower:]
or[:upper:]
(donc la première est ignorée). Même en français,œ -> Œ
estc5 93 -> c5 92
en UTF-8 etbd -> bc
en iso8859-15.Bien que cela ait les mêmes limites déjà mentionnées que la
tr
solution proposée par Stéphane Chazelas, c'est une autre façon de le faire:PRODUCTION
Je larguer
stderr
en/dev/null
là parce quedd
fournit également des statistiques de toutes ses opérations sur le2
descripteur de fichier. Cela peut être utile selon ce que vous faites, mais ce n'était pas le cas pour cette démonstration. Toutes les autres choses que vous pouvez fairedd
s'appliquent toujours, par exemple:PRODUCTION:
la source
aBc
n'est pas converti enAbC
).Si votre objectif principal est de convertir un fichier de classe inférieure en classe supérieure, pourquoi ne l'utilisez-vous pas
tr
etSTDOUT
pour convertir votre fichier:Où se
FILENAME
trouve votre fichier d'origine. Où seFILENAME2
trouve votre fichier de sortie converti.la source
é
par exemple (au moins dans mon fichier).utilisant
awk
:la source
>file.txt
commencerait par tronquer le fichierruby
a une méthode de chaîne pour cela, une utilisation similaire à partir de la ligne de commande commeperl
Voir aussi Ruby-doc Encoding
la source
Restez simple. Le filtre conçu pour traduire les caractères est
tr
.la source