Necesito una utilidad internacionalizada que haga lo mismo que tr
:obtiene el carácter del flujo y lo sustituye por el carácter correspondiente.
No es una solución de caso particular como de menor a mayor, pero se necesita una solución de caso general.
Sin gorillion canalizado sed
llama si es posible.
Tenga en cuenta que tr
no funciona en Linux:traduce bytes, no caracteres. Esto falla con codificaciones multibyte.
$ tr --version | head -n 1
tr (GNU coreutils) 8.23
$ echo $LC_CTYPE
en_US.UTF-8
$ echo 'Ångstrom' | tr Æ Œ
Ņngstrom
Respuesta aceptada:
GNU sed
funciona con caracteres de varios bytes. Entonces:
$ echo é½Æ | sed 'y/é½Æ/ABŒ/'
ABŒ
No es tanto que GNU tr
no se ha internacionalizado, pero no admite caracteres de varios bytes (como los que no son ASCII en las configuraciones regionales UTF-8). GNU tr
funcionaría con Æ
, Œ
siempre y cuando fueran de un solo byte como en el juego de caracteres iso8859-15.
Más sobre eso en ¿Cómo hacer que tr sea consciente de los caracteres que no son ASCII (Unicode)?
En cualquier caso, eso no tiene nada que ver con Linux, se trata del tr
implementación en el sistema. Si ese sistema usa Linux como kernel o tr
está construido para Linux o usa la API del kernel de Linux no es relevante ya que esa parte del tr
la funcionalidad tiene lugar en el espacio del usuario.
caja ocupada tr
y GNU tr
son los que se encuentran más comúnmente en las distribuciones de software creado para Linux y no admiten caracteres de varios bytes, pero hay otros que se han adaptado a Linux como tr
de la caja de herramientas de la herencia (portada de OpenSolaris) o de ast-open que lo hacen.
Tenga en cuenta que sed
's y
no admite rangos como a-z
. También tenga en cuenta que si ese script que contiene sed 'y/é½Æ/ABŒ/'
está escrito en el juego de caracteres UTF-8, ya no funcionará como se espera si se llama en una configuración regional donde UTF-8 no es el juego de caracteres.
Una alternativa podría ser usar perl
:
perl -Mopen=locale -Mutf8 -pe 'y/a-zé½Æ/A-ZABŒ/'
Arriba, se espera que el código perl esté en UTF-8, pero procesará la entrada en la codificación de la configuración regional (y la salida en la misma codificación). Si se llama en una configuración regional UTF-8, transliterará un UTF-8 Æ
(0xc3 0x86) a un UTF-8 Œ
(0xc5 0x92) y en un ISO8859-15 igual pero para 0xc6 -> 0xbc.
En la mayoría de los shells, tener esos caracteres UTF-8 entre comillas simples debería estar bien incluso si el script se llama en una configuración regional donde UTF-8 no es el juego de caracteres (una excepción es yash
que se quejaría si esos bytes no forman caracteres válidos en la configuración regional). Sin embargo, si está utilizando otras comillas que no sean comillas simples, podría causar problemas. Por ejemplo,
perl -Mopen=locale -Mutf8 -pe "y/♣`/&'/"
fallaría en una configuración regional donde el juego de caracteres es BIG5-HKSCS porque la codificación de (0x5c) también está contenido en algunos otros caracteres allí (como
α
:0xa3 0x5c, y la codificación UTF-8 de ♣
termina en 0xa3).
En cualquier caso, no esperes cosas como
perl -Mopen=locale -Mutf8 -pe 'y/Á-Ź/A-Z/'
para trabajar en la eliminación de acentos agudos. Lo anterior es en realidad solo
perl -Mopen=locale -Mutf8 -pe 'y/x{c1}-x{179}/x{41}-x{5a}/'
Es decir, el rango se basa en los puntos de código Unicode. Por lo tanto, los rangos no serán útiles fuera de secuencias muy bien definidas que se encuentran en el "derecho ” orden en Unicode como A-Z
, 0-9
.
Si desea eliminar los acentos agudos, deberá utilizar herramientas más avanzadas como:
perl -Mopen=locale -MUnicode::Normalize -pe '
$_ = NFKD($_); s/x{301}//g; $_ = NFKC($_)'
Eso es usar formas de normalización Unicode para descomponer caracteres, eliminar los acentos agudos (aquí la forma combinada U+0301
) y recomponer.
Otra herramienta útil para transliterar Unicode es uconv
de la UCI. Por ejemplo, lo anterior también podría escribirse como:
uconv -x '::NFKD; u0301>; ::NFKC;'
Aunque solo funcionaría con datos UTF-8. Necesitarías:
iconv -t utf-8 | uconv -x '::NFKD; u0301>; ::NFKC;' | iconv -f utf-8
Para poder procesar datos en la configuración regional del usuario.