¿Qué está pasando en el siguiente fragmento de código? No estoy obteniendo mi salida esperada.
Creo que fue un error, pero ocurre para 2 programas diferentes (uniq y sort), por lo que sospecho que tiene algo que ver con ... bueno, no sé qué ... de ahí la pregunta.
Los primeros 3 (de 4) ejemplos funcionan, pero el cuarto falla.
Esperaría el mismo comportamiento para todos y cada uno de los personajes.
es decir. para imprimir 2 líneas (de las 3 líneas de entrada) ... pero en el cuarto caso, solo obtengo 1 línea (para ambos sort -u
y uniq
); ¡Los dos lins idénticos se desvanecen!
He convertido la salida '\ n' en espacio para una vista compacta.
Estoy usando uniq y ordenar desde (GNU coreutils) 7.4 ... ejecutándose en el escritorio Ubuntu 10.04.3 LTS.
La secuencia de comandos:
{
locale -k LC_COLLATE
echo
for c1 in x 〼 ;do
for c2 in z 〇 ;do
echo -n "asis : "; echo -e "$c1\n$c2\n$c2" |tr '\n' ' ';echo
echo -n "uniq : "; echo -e "$c1\n$c2\n$c2" |uniq |tr '\n' ' ';echo
echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
echo
done
echo
done
}
La salida:
collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"
asis : x z z
uniq : x z
sort -u: x z
asis : x 〇 〇
uniq : x 〇
sort -u: 〇 x
asis : 〼 z z
uniq : 〼 z
sort -u: 〼 z
asis : 〼 〇 〇
uniq : 〼
sort -u: 〼
# In the last example (of 4) where did the '〇' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#
sort
solo (sin la opción -u ) ... no engulle caracteres ... Lo que entra, sale ... Sin embargo, como puede esperarse de Gilles, la explicación de los caracteres unicode "exóticos" que tienen el mismo valor canónico , estos los caracteres no se ordenan, aparte de eso, se muestran como un grupo FIFO sin clasificar en la "parte superior" de la salida de la clasificación ... Entonces, realmente hay dos problemas aquí: 1. Los caracteres no se ordenan como podría ser "ingenuamente "esperado, y 2. La característica" única "de ambossort
yuniq
perder datos (en algunos casos).sort -u
yuniq
funciona bien con:LC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u
(o|uniq
)Respuestas:
Versión corta: la recopilación no funciona realmente en las utilidades de línea de comandos.
Versión más larga: la función subyacente para comparar dos cadenas es
strcoll
. La descripción no es muy útil, pero el método conceptual de operación es convertir ambas cadenas a una forma canónica y luego comparar las dos formas canónicas. La funciónstrxfrm
construye esta forma canónica.Observemos las formas canónicas de algunas cadenas (con GNU libc, bajo compresión de Debian):
Como puede ver, 〼 y 〇 tienen la misma forma canónica. Creo que es porque estos caracteres no se mencionan en las tablas de clasificación de la
en_US.UTF-8
configuración regional. Sin embargo, están presentes en una localidad japonesa.El código fuente de los datos locales (en Debian squeeze) está en
/usr/share/i18n/locales/en_US
, que incluye/usr/share/i18n/locales/iso14651_t1_common
. Este archivo no tiene una entrada paraU3007
oU303C
, ni están incluidos en ningún rango que pueda encontrar.No estoy familiarizado con las reglas para construir el orden de clasificación , pero por lo que entiendo, la redacción relevante es
Parece que Glibc ignora los caracteres que no se especifican. No sé si hay una falla en mi comprensión de la especificación POSIX, si me perdí algo en la definición de la configuración regional de Glibc o si hay un error en el compilador de la configuración regional de Glibc.
fuente
charmaps/UTF-8
no dice nada sobre la colación, es lolocales/en_US
que importa. La primera regla deLC_COLLATE
es: no usarLC_COLLATE
. En la configuración regional C (= POSIX), la clasificación es razonable (basada estrictamente en valores de caracteres numéricos).LC_COLLATE=C
... gracias ...Para "con seguridad"
sort
cadenas Unicode, tal vez eche un vistazo amsort
:http://www.billposer.org/Software/msort.html
fuente
msort
. La GUI opcional hace que la introducción sea un poco más fácil para tener una idea de lo que se ofrece. Ser capaz de copiar el comando generado es muy útil ... Y sí, ordena los caracteres unicode, pero (¿no te encantan esos "peros":) ... pero no tiene una opción única : (... como se menciona en el enlace que publicaste:Capabilities of GNU sort and BSD sort lacking in msort are the ability to merge files without sorting them (the --merge option) and the ability to emit only the first of an equal run (the --unique option)
... Aunque el tipo funciona :)