Risposte:
Ecco un modo semplice in sed
:
$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy
o un modo più breve con GNU sed
, lavorando con qualsiasi carattere per il quale esiste una conversione in minuscolo <-> maiuscolo nella tua locale:
$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy
se puoi usare altri strumenti, come:
perl
(limitato alle lettere ASCII):
$ echo qWeRtY | perl -pe 'y/[a-z][A-Z]/[A-Z][a-z]/'
QwErTy
perl
(più generalmente):
$ echo 'αΒγ' | perl -Mopen=locale -pe 's/(\p{Ll})|(\p{Lu})/uc($1).lc($2)/ge'
ΑβΓ
sed
e un caso alternativo nell'input. Usa sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
invece (ancora specifico per GNU). Il primo converte solo le 26 lettere latine ASCII, mentre il secondo converte qualsiasi lettera riconosciuta come tale dalle impostazioni internazionali. Quello tr
ha senso solo in locali ASCII. Quello perl
funziona solo per lettere latine ASCII.
POSIX, ciò non può essere fatto sed
se non fornendo l'insieme completo di lettere che si desidera traslitterare come ha mostrato @cuonglm .
Si potrebbe fare con tr
però, ed è quello che tr
serve per (traslitterare):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
Tuttavia, su Linux ha dei limiti. Delle 3 tr
implementazioni che si trovano comunemente sui sistemi basati su Linux:
tr
, che funziona solo per set di caratteri a byte singolo. Ad esempio, su Stéphane Chazelas
nelle lingue UTF-8, che fornisce sTéPHANE cHAZELAS
invece di sTÉPHANE cHAZELAS
. Questa è una limitazione nota di GNU tr
.tr
dal cimelio di cimelio, che non funziona (ottieni stéphane chazelas
).tr
.Su FreeBSD però funziona bene. Ti aspetteresti che funzioni anche su sistemi Unix certificati.
La bash
shell ha un operatore dedicato per questo:
in=AbCdE
out=${in~~}
Con zsh -o extendedglob
:
out=${in//(#b)(([[:lower:]])|([[:upper:]]))/${(U)match[2]}${(L)match[3]}}
ⴠ
(e2 b4 a0) è Ⴠ
(e1 83 80); entrambi i
(69) e ı
(c4 b1) hanno I
(49) in maiuscolo (tranne che nei locali turchi dove i
diventa İ
). Il motivo per cui non funziona con GNU tr
è che GNU tr
funziona con byte e non con caratteri.
[:lower:]
o [:upper:]
(in modo che il primo viene ignorato). Anche in francese, œ -> Œ
è c5 93 -> c5 92
in UTF-8 e bd -> bc
in iso8859-15.
Sebbene questo abbia gli stessi limiti già menzionati come la tr
soluzione offerta da Stéphane Chazelas, è un altro modo per farlo:
{ echo QWERTYqwerty | dd conv=lcase
echo QWERTYqwerty | dd conv=ucase
} 2>/dev/null
qwertyqwerty
QWERTYQWERTY
I discarica stderr
in /dev/null
là perché dd
fornisce anche le statistiche di tutte le sue operazioni sul 2
descrittore di file. Questo può essere utile a seconda di ciò che stai facendo, ma non era per questa dimostrazione. Tutte le altre cose che puoi fare con dd
si applicano ancora, ad esempio:
echo QWERTYqwerty | dd bs=1 cbs=6 conv=unblock,ucase 2>/dev/null
QWERTY
QWERTY
aBc
non viene convertito in AbC
).
Se il tuo obiettivo principale è convertire un file da minuscole a maiuscole, perché non lo usi tr
e STDOUT
per convertire il tuo file:
$cat FILENAME | tr a-z A-Z > FILENAME2
Dov'è il FILENAME
tuo file originale. Dov'è il FILENAME2
tuo file di output convertito.
é
ad esempio (almeno nel mio file).
utilizzando awk
:
awk '{print tolower($0)}' file.txt | tee file.txt
>file.txt
inizierebbe troncando il file
ruby
ha un metodo stringa per questo, un uso simile dalla riga di comando come perl
$ echo 'qWeRtY' | ruby -pe '$_.swapcase!'
QwErTy
Vedi anche la codifica ruby-doc
$ ruby -e 'puts Encoding.default_external'
UTF-8
$ echo 'αΒγ' | ruby -pe '$_.swapcase!'
ΑβΓ
Mantieni semplice cosa semplice. Il filtro progettato per tradurre i caratteri è tr
.
echo 1ude1UDE | tr [:upper:][:lower:] [:lower:][:upper:]
tr
sarebbe più adatto dised
.