¿Convertir todo el texto de mayúsculas a minúsculas y viceversa?

17

Mi pregunta es ¿cómo puedo convertir todo el texto de mayúsculas a minúsculas y viceversa? Eso es cambiar los casos de todas las letras. Tiene que hacerse con un sedreemplazo de alguna manera.

MEZesUBI
fuente
44
trsería más adecuado que sed.
choroba

Respuestas:

20

Aquí hay una forma directa de sed:

$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy

o una forma más corta con GNU sed, trabajando con cualquier carácter para el que exista una conversión en minúscula <-> mayúscula en su localidad:

$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy

si puedes usar otras herramientas, como:

perl (limitado a letras ASCII):

$ echo qWeRtY | perl -pe 'y/[a-z][A-Z]/[A-Z][a-z]/'
QwErTy

perl (más generalmente):

$ echo 'αΒγ' | perl -Mopen=locale -pe 's/(\p{Ll})|(\p{Lu})/uc($1).lc($2)/ge'
ΑβΓ
Cuonglm
fuente
3
Su segundo asume un GNU sedy un caso alternativo en la entrada. Utilice en su sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'lugar (todavía GNU específico). La primera solo convierte las 26 letras latinas ASCII, mientras que la segunda convierte cualquier letra reconocida como tal por su localidad. El trúnico tiene sentido en las configuraciones regionales ASCII. El perlúnico funciona para letras latinas ASCII.
Stéphane Chazelas
16

POSITIVAMENTE, eso no se puede hacer, sedexcepto al proporcionar el conjunto completo de letras que desea transliterar como se ha mostrado en @cuonglm .

Sin trembargo, podría hacerse con , y para eso trsirve (transliterar):

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

Sin embargo, en Linux, tiene limitaciones. De las 3 trimplementaciones que se encuentran comúnmente en sistemas basados ​​en Linux:

  • con GNU tr, eso solo funciona para conjuntos de caracteres de un solo byte. Por ejemplo, en Stéphane Chazelasconfiguraciones regionales UTF-8, eso da en sTéPHANE cHAZELASlugar de sTÉPHANE cHAZELAS. Esa es una limitación conocida de GNU tr.
  • con trde la herencia de herramientas de la herencia, eso no funciona (obtienes stéphane chazelas).
  • Ese no es el tipo de cosas que busybox trhará.

Sin embargo, en FreeBSD funciona bien. Es de esperar que funcione bien en sistemas Unix certificados también.


El bashshell tiene un operador dedicado para eso:

in=AbCdE
out=${in~~}

Con zsh -o extendedglob:

out=${in//(#b)(([[:lower:]])|([[:upper:]]))/${(U)match[2]}${(L)match[3]}}
Stéphane Chazelas
fuente
Entonces, ¿en el mundo de escritorio solo OSX lo hace? ¿Por qué no puede funcionar? ¿Son solo las diferentes implementaciones, ya que parece que hay un desplazamiento constante en el valor hexadecimal entre la versión en minúsculas del carácter acentuado y su contraparte en mayúscula?
1
@ illuminÉ, no estoy seguro de lo que quieres decir con mundo de escritorio . AFAICS, el problema es con GNU, la mayoría de los Unices tienen "escritorios". Además de ASCII y algunos conjuntos de caracteres iso8859, no sé si se puede generalizar el desplazamiento hexagonal, y eso no tendría sentido con codificaciones como UTF-8. Por ejemplo, en UTF-8, mayúscula (e2 b4 a0) es (e1 83 80); ambos i(69) y ı(c4 b1) tienen I(49) como mayúsculas (excepto en los locales turcos donde se iconvierte İ). La razón por la que no funciona con GNU tres que GNU trfunciona con bytes y no con caracteres.
Stéphane Chazelas
Me refería a la corriente principal, pero en realidad no tiene sentido, así que gracias por el aviso. Solo miré los caracteres acentuados en francés (y realmente solo "é") e hice suposiciones muy simplistas, olvidando nuevamente que se trata de bytes. ¿Pero la reliquia? ¡Iré a leer esa respuesta otra vez!
1
@ illuminÉ, para la herencia, es un problema diferente, parece que solo admite una aparición de [:lower:]o [:upper:](por lo que se ignora la primera). Incluso en francés, œ -> Œestá c5 93 -> c5 92en UTF-8 y bd -> bcen iso8859-15.
Stéphane Chazelas
2

Aunque esto tiene las mismas limitaciones ya mencionadas como la trsolución ofrecida por Stéphane Chazelas, es otra forma de hacerlo:

{   echo QWERTYqwerty | dd conv=lcase
    echo QWERTYqwerty | dd conv=ucase 
} 2>/dev/null

SALIDA

qwertyqwerty
QWERTYQWERTY

Yo tiro stderrhacia /dev/nullallí porque ddtambién proporciona estadísticas de todas sus operaciones en el 2descriptor de archivo. Esto puede ser útil dependiendo de lo que esté haciendo, pero no fue para esta demostración. Todas las demás cosas que puede hacer ddaún se aplican, por ejemplo:

echo QWERTYqwerty | dd bs=1 cbs=6 conv=unblock,ucase 2>/dev/null

SALIDA:

QWERTY
QWERTY
mikeserv
fuente
Sin embargo, no cambia el caso (ya aBcque no se convierte en AbC).
Stéphane Chazelas
1
@ StéphaneChazelas: cierto, pero a menos que haya entendido mal, esa no era la pregunta, ¿verdad?
mikeserv
2

Si su objetivo principal es convertir un archivo de clase inferior a clase superior, ¿por qué no utiliza try STDOUTpara convertir su archivo?

$cat FILENAME | tr a-z A-Z > FILENAME2

¿Dónde FILENAMEestá tu archivo original? ¿Dónde FILENAME2está tu archivo de salida convertido?

Almiar
fuente
No funcionaba con caracteres acentuados, como épor ejemplo (al menos en mi archivo).
Sigur
1

utilizando awk:

awk '{print tolower($0)}' file.txt | tee file.txt
Adicto al alcohol
fuente
¿Estás seguro de que esto va a funcionar? >file.txtcomenzaría truncando el archivo
iruvar
2
Entonces obviamente no lo has probado.
Stéphane Chazelas
0

ruby tiene un método de cadena para eso, uso similar de la línea de comando como perl

$ echo 'qWeRtY' | ruby -pe '$_.swapcase!'
QwErTy

Ver también codificación ruby-doc

$ ruby -e 'puts Encoding.default_external'
UTF-8
$ echo 'αΒγ'  | ruby -pe '$_.swapcase!'
ΑβΓ
Sundeep
fuente
-1

Mantenga la cosa simple simple. El filtro diseñado para traducir caracteres es tr.

echo 1ude1UDE | tr [:upper:][:lower:] [:lower:][:upper:]
rogelio
fuente
1
Esa es una versión rota (debido a las citas que faltan alrededor de los operadores globales) de una respuesta que ya se dio 2 años antes
Stéphane Chazelas