¿Cómo convertir archivos txt UTF-8 a mayúsculas en bash?

10

Tengo algunos archivos .txt UTF-8 que me gustaría convertir a mayúsculas. Si fuera solo ASCII, podría usar:

tr [:lower:] [:upper:]

Pero como estoy trabajando con diacríticos y otras cosas, no parece funcionar. Supongo que podría funcionar si configuro la configuración regional adecuada, pero necesito que este script sea portátil.

VPeric
fuente

Respuestas:

14

Todo:

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

(no se olvide de las comillas, de otro modo que no va a funcionar si hay un archivo llamado :, l... o ren el directorio actual) o:

awk '{print toupper($0)}'

o:

dd conv=ucase

están destinados a convertir caracteres a mayúsculas de acuerdo con las reglas definidas en la configuración regional actual. Sin embargo, incluso cuando las configuraciones regionales usan UTF-8 como el conjunto de caracteres y definen claramente la conversión de minúsculas a mayúsculas, al menos GNU dd, GNU try mawk(el valor predeterminado awken Ubuntu, por ejemplo) no las siguen. Además, no hay una forma estándar de especificar configuraciones regionales que no sean Co POSIX, por lo que si desea convertir los archivos UTF-8 a mayúsculas de manera portátil, independientemente de la configuración regional actual, no tiene suerte con el cofre de herramientas estándar.

Como a menudo, para la portabilidad, su mejor apuesta puede ser perl:

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

Ahora, debes tener en cuenta que no todos están de acuerdo sobre cuál es la versión en mayúsculas de un personaje específico.

Por ejemplo, en locales turcos, las mayúsculas ino son I, sino İ( <U0130>). Aquí con la herramienta trde comprobación de herencia en lugar 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:]'
İÍ

En mi sistema, la perlconversión a superior se define en /usr/share/perl/5.14/unicore/To/Upper.pl, y encuentro que se comporta de manera diferente en algunos caracteres de la libc de GNU toupper()en la C.UTF8configuración regional, por ejemplo, perlsiendo más precisa. Por ejemplo perl, convierte correctamente ɀ a Ɀ , la libc de GNU (2.17) no.

Stéphane Chazelas
fuente
Para lo que vale, estoy trabajando con letras checas (y el ejemplo que usó es en realidad eslovaco), donde todas las letras mayúsculas están claramente definidas, pero el conjunto de configuraciones regionales probablemente sea C y no checo, así que eso es un problema. Perl ya se usa en esta cadena de herramientas, por lo que agregar otro uso podría no ser tan malo. Gracias por la explicación detallada, por cierto!
VPeric
3

Creo que puedes hacer esto awky su toupperfunción.

Por ejemplo

No funciona con GNU tr:

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

Funciona con GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ
slm
fuente
@StephaneChazelas: gracias, cambié el ejemplo de falla.
slm
Eso depende de la localización actual y en la tro awkaplicación. Por ejemplo, la mayoría trconvertirá correctamente los caracteres cuando se encuentre en un entorno local UTF8, de acuerdo con el entorno local actual, GNU trno. mawkno lo hace
Stéphane Chazelas
1
En realidad, en FreeBSD (9.1), es al revés. Funciona con tr, pero no conawk
Stéphane Chazelas
@StephaneChazelas - No estoy tan versado en las variaciones 8-). Alguien acaba de votar, ¿por qué?
slm
2

Esto funciona con OS X trpero no con GNU tr:

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

Esto funciona con gawkpero no con mawko nawk(que está /usr/bin/awken OS X):

awk '{print toupper($0)}'

Otra opción es usar GNU sed:

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

En Bash 4.0 y versiones posteriores también puede usar la ^^expansión de parámetros:

while IFS= read -r l;do printf %s\\n "${l^^}";done
nisetama
fuente