En todas partes veo a alguien que necesita obtener una lista ordenada y única, a la que siempre se dirigen sort | uniq
. Nunca he visto ningún ejemplo en el que alguien use en su sort -u
lugar. Por qué no? ¿Cuál es la diferencia, y por qué es mejor usar uniq que la bandera única para ordenar?
120
Respuestas:
sort | uniq
existía antessort -u
y es compatible con una gama más amplia de sistemas, aunque casi todos los sistemas modernos son compatibles-u
: es POSIX. Es principalmente un retroceso a los días ensort -u
que no existía (y las personas no tienden a cambiar sus métodos si la forma en que saben continúa funcionando, solo mirenifconfig
vs.ip
adopción).Los dos probablemente se fusionaron porque eliminar duplicados dentro de un archivo requiere ordenación (al menos, en el caso estándar), y es un caso de uso extremadamente común. También es más rápido internamente como resultado de poder realizar ambas operaciones al mismo tiempo (y debido al hecho de que no requiere IPC entre
uniq
ysort
). Especialmente si el archivo es grande,sort -u
probablemente usará menos archivos intermedios para ordenar los datos.En mi sistema constantemente obtengo resultados como este:
Tampoco oculta el código de retorno de
sort
, que puede ser importante (en los shells modernos hay formas de obtener esto, por ejemplo,bash
la$PIPESTATUS
matriz, pero esto no siempre fue cierto).fuente
sort | uniq
porque 9 de cada 10 veces, de hecho, estoy conectadouniq -c
.sort -u
era parte de la 7ª Edición de UNIX, alrededor de 1979. Las versionessort
sin soporte-u
son verdaderamente arcaicas, o se escribieron sin prestar atención al estándar de facto antes del estándar de jure de POSIX. Ver también Stack Overflow Sort & uniq en Linux Shell desde 2010.ip
. Es 2016 y esta publicación en 2013, pero solo sé sobre elip
comando ahora.uniq -c
" (y tal vez canalizando una vez mássort -nr | head
). Me preguntaba a qué equivalesort | uniq
en Vim cuando descubrí que Vim tiene el:sort u
mando. Y TILsort -u
existe también.sort -n | uniq
contrasort -n -u
. Por ejemplo, los espacios en blanco iniciales y finales serán vistos como duplicadossort -n -u
por el primero, pero no por el primero.echo -e 'test \n test' | sort -n -u
vuelvetest
, peroecho -e 'test \n test' | sort -n | uniq
devuelve ambas líneas.Una diferencia es que
uniq
tiene una serie de opciones adicionales útiles, como omitir campos para comparar y contar el número de repeticiones de un valor.sort
La-u
bandera solo implementa la funcionalidad deluniq
comando sin adornos .fuente
sort -u
No se puede pasar la salida deuniq
para usar algunas de las opciones útiles de esta última, como omitir campos para comparar y contar el número de repeticiones".Con
sort
s yuniq
s compatibles con POSIX (GNUuniq
actualmente no es compatible en ese sentido), hay una diferencia en quesort
usa el algoritmo de clasificación de la configuración regional para comparar cadenas (generalmente se usarástrcoll()
para comparar cadenas) mientras seuniq
verifica la identidad del valor de byte (generalmente se usarástrcmp()
) .Eso es importante por al menos dos razones.
En algunos entornos locales, especialmente en los sistemas GNU, hay diferentes caracteres que ordenan lo mismo. Por ejemplo, en la configuración regional en_US.UTF-8 en un sistema GNU, todos los caracteres ①②③④⑤⑥⑦⑧⑨⑩ ... y muchos otros se ordenan de la misma manera porque su orden de clasificación no está definido. Los dígitos árabes 0123456789 se clasifican de la misma manera que sus contrapartes índicas árabes orientales (٠١٢٣٤٥٦٧٨٩).
Para
sort -u
, ① ordena lo mismo que ② y 0123 lo mismo que ٠١٢٣, porsort -u
lo que retendría solo uno de cada uno, mientras que parauniq
(no GNUuniq
que usastrcoll()
(excepto con-i
)), ① es diferente de ② y 0123 es diferente de ٠١٢٣, poruniq
lo que consideraría todos 4 únicos.strcoll
solo puede comparar cadenas de caracteres válidos (el comportamiento no está definido según POSIX cuando la entrada tiene secuencias de bytes que no forman caracteres válidos), mientras questrcmp()
no le importan los caracteres, ya que solo hace una comparación byte a byte. Entonces, esa es otra razón por la cual essort -u
posible que no le proporcione todas las líneas únicas si algunas de ellas no forman un texto válido.sort|uniq
, aunque todavía no se ha especificado en la entrada sin texto, en la práctica es más probable que le proporcione líneas únicas por ese motivo.Además de esas sutilezas, una cosa que no se ha notado hasta ahora es que
uniq
compara la línea completa léxicamente, mientras quesort
la-u
comparación se basa en la especificación de clasificación dada en la línea de comando.fuente
Prefiero usarlo
sort | uniq
porque cuando trato de usar la-u
opción (eliminar duplicados) para eliminar duplicados que involucran cadenas de mayúsculas y minúsculas, no es tan fácil entender el resultado.Nota: antes de poder ejecutar los ejemplos a continuación, debe simular la secuencia de clasificación C estándar haciendo lo siguiente:
Por ejemplo, si quiero ordenar un archivo y eliminar duplicados, al mismo tiempo, mantengo distintos casos de cadenas.
Esta confusión se resuelve al no usar la
-u
opción para eliminar duplicados. Usaruniq
es más predecible. Lo siguiente primero ordena e ignora el caso y luego lo pasauniq
para eliminar los duplicados.fuente
-u
opción desort
salidas el primero de una ejecución igual (ver página de manual) Por lo tanto,sort -fu
recoge la primera aparición de cada línea única que no distingue entre mayúsculas y minúsculas. La lógica que sesort
usa para eliminar duplicados es predecible.Otra diferencia que descubrí hoy es al ordenar en base a un delimitador donde se
sort -u
aplica la bandera única solo en la columna con la que se ordena.fuente