GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿cómo hacer que Tr sea consciente de los caracteres que no son ascii (unicode)?

Estoy tratando de eliminar algunos caracteres del archivo (UTF-8). Estoy usando tr para este propósito:

tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat 

El archivo contiene algunos caracteres extraños (como "Латвийская" o "àé"). tr no parece entenderlos:los trata como no alfa y también los elimina.

Intenté cambiar algunas de mis configuraciones locales:

LC_CTYPE=C LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=ru_RU.UTF-8 tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat

Desafortunadamente, ninguno de estos funcionó.

¿Cómo puedo hacer tr entiende Unicode?

Respuesta aceptada:

Esa es una limitación conocida (1, 2, 3, 4, 5, 6) de la implementación GNU de tr .

No es tanto que no sea compatible con extranjero , caracteres no ingleses o no ASCII, pero que no admite caracteres de varios bytes.

Esos caracteres cirílicos se tratarían bien, si estuvieran escritos en el juego de caracteres iso8859-5 (un byte por carácter) (y su configuración regional estaba usando ese juego de caracteres), pero su problema es que está usando UTF-8 donde no es ASCII los caracteres se codifican en 2 o más bytes.

GNU tiene un plan (ver también) para arreglar eso y el trabajo está en marcha pero aún no está listo.

FreeBSD o Solaris tr no tienes el problema.

Mientras tanto, para la mayoría de los casos de uso de tr , puede usar GNU sed o GNU awk que admiten caracteres de varios bytes.

Por ejemplo, su:

tr -cs '[[:alpha:][:space:]]' ' '

podría escribirse:

gsed -E 's/( |[^[:space:][:alpha:]])+/ /'

o:

gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'

Para convertir entre minúsculas y mayúsculas (tr '[:upper:]' '[:lower:]' ):

gsed 's/[[:upper:]]/l&/g'

(que l es una L minúscula , no el 1 dígito).

o:

gawk '{print tolower($0)}'

Para portabilidad, perl es otra alternativa:

perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'

Si sabe que los datos se pueden representar en un conjunto de caracteres de un solo byte, puede procesarlos en ese conjunto de caracteres:

(export LC_ALL=ru_RU.iso88595
 iconv -f utf-8 |
   tr -cs '[:alpha:][:space:]' ' ' |
   iconv -t utf-8) < Russian-file.utf8

Linux
  1. Cómo hacer que una computadora vieja vuelva a ser útil

  2. Cómo asegurarse de que una aplicación siga ejecutándose en Linux

  3. Dos versiones de python en linux. cómo hacer que 2.7 sea el predeterminado

  4. ¿Cómo escribir caracteres especiales en Linux?

  5. ¿Cómo hacer una copia de seguridad diferencial en Linux?

Cómo hacer un archivo ejecutable en Linux

Cómo hacer un USB de arranque múltiple en Linux y Windows

Cómo Linux puede hacer tu vida más fácil

Cómo quitar (^M) caracteres de un archivo en Linux

¿Cómo hacer un archivo ejecutable en la terminal de Linux?

Cómo hacer un servidor de Minecraft en distribuciones de Linux