GNU/Linux >> Tutoriales Linux >  >> Linux

¿Usando Uniq en texto Unicode?

Quiero eliminar líneas duplicadas de un archivo con palabras en escritura siríaca. El archivo fuente tiene 3 líneas, la primera y la tercera son idénticas.

$ cat file.txt 
ܐܒܘܢ
ܢܗܘܐ
ܐܒܘܢ

Cuando uso sort y uniq , el resultado supone que las 3 líneas son idénticas, lo cual es incorrecto:

$ cat file.txt | sort | uniq -c
      3 ܐܒܘܢ

Establecer explícitamente el idioma siríaco tampoco ayuda.

$ LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c      
     3 ܐܒܘܢ

¿Por qué sucedería eso?
Estoy usando Kubuntu 18 y bash, si eso importa.

Respuesta aceptada:

La implementación GNU de uniq como se encuentra en Ubuntu, con -c , no informa recuentos de idénticos contiguos líneas pero recuentos de líneas contiguas que ordenan lo mismo¹.

La mayoría de las configuraciones regionales internacionales en los sistemas GNU tienen el error de que muchos caracteres completamente no relacionados se han definido con el mismo orden de clasificación, la mayoría de ellos porque su orden de clasificación no está definido en absoluto. La mayoría de los demás sistemas operativos se aseguran de que todos los caracteres tengan un orden de clasificación diferente.

$ expr ܐ = ܒ
1

(expr 's = operador, para argumentos que no son numéricos, devuelve 1 si los operandos tienen el mismo orden, 0 de lo contrario).

Es lo mismo con ar_SY.UTF-8 o en_GB.UTF-8 .

Lo que necesitaría es una configuración regional en la que a esos caracteres se les haya dado un orden de clasificación diferente. Si Ubuntu tuviera configuraciones regionales para el idioma siríaco, podría esperar que esos caracteres tuvieran un orden de clasificación diferente, pero Ubuntu no tiene tales configuraciones regionales.

Puede mirar la salida de locale -a para obtener una lista de las configuraciones regionales admitidas. Puede habilitar más locales ejecutando dpkg-reconfigure locales como root . También puede definir más locales manualmente usando localedef basado en los archivos de definición en /usr/share/i18n/locales , pero no encontrará datos para el idioma siríaco allí.

Tenga en cuenta que en:

LC_COLLATE=syr_SY.utf8 cat file.txt | sort | uniq -c

Solo está configurando la variable LC_COLLATE para el cat comando (que no afecta la forma en que genera el contenido del archivo, cat no le importa la intercalación ni siquiera la codificación de caracteres, ya que no es una utilidad de texto). Te gustaría configurarlo para ambos sort y uniq . También querrá configurar LC_CTYPE a una configuración regional que tenga un juego de caracteres UTF-8.

Como su sistema no tiene syr_SY.utf8 locale, eso es lo mismo que usar el C configuración regional (la configuración regional predeterminada).

En realidad, aquí la configuración regional C o C.UTF-8 es probablemente la configuración regional que le gustaría usar.

En esas configuraciones regionales, el orden de intercalación se basa en el punto de código, punto de código Unicode para C.UTF-8, valor de byte para C, pero termina siendo lo mismo que la codificación de caracteres UTF-8 tiene esa propiedad.

$ LC_ALL=C expr ܐ = ܒ
0
$ LC_ALL=C.UTF-8 expr ܐ = ܒ
0

Entonces con:

(export LANG=ar_SY.UTF-8 LC_COLLATE=C.UTF-8 LANGUAGE=syr:ar:en
 unset LC_ALL
 sort <file | uniq -c)

Tendría un LC_CTYPE con UTF-8 como juego de caracteres, un orden de clasificación basado en el punto de código y otras configuraciones relevantes para su región, por ejemplo, mensajes de error en siríaco o árabe si GNU coreutils sort o uniq los mensajes se habían traducido a esos idiomas (todavía no lo han hecho).

Relacionado:¿Cómo marcar varios contactos para enviar el mismo texto como BCC, función que existe en Android?

Si no te importan esos otros configuración, es igual de fácil (y también más portátil) de usar:

<file LC_ALL=C sort | LC_ALL=C uniq -c

O

(export LC_ALL=C; <file sort | uniq -c)

como ya ha mostrado @isaac.


Linux
  1. ¿Adjuntar texto al final de un archivo de texto?

  2. Cómo eliminar palabras duplicadas de un archivo de texto sin formato usando el comando de Linux

  3. ¿Cómo contar el número de valores únicos de un campo en un archivo de texto delimitado por tabuladores?

  4. Usando nc para transferir archivos grandes

  5. Cómo ordenar un archivo en el lugar

Uso del archivo de configuración SSH

Cómo bloquear un archivo de texto en Linux usando el comando flock

Cómo:una introducción al uso de Git

Transferir archivos usando WinSCP

Encuentre y reemplace texto en un archivo entre un rango de líneas usando sed

¿Cómo inserto texto en la primera línea de un archivo usando sed?