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 -ulugar. Por qué no? ¿Cuál es la diferencia, y por qué es mejor usar uniq que la bandera única para ordenar?
120

Respuestas:
sort | uniqexistía antessort -uy 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 -uque no existía (y las personas no tienden a cambiar sus métodos si la forma en que saben continúa funcionando, solo mirenifconfigvs.ipadopció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
uniqysort). Especialmente si el archivo es grande,sort -uprobablemente 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,bashla$PIPESTATUSmatriz, pero esto no siempre fue cierto).fuente
sort | uniqporque 9 de cada 10 veces, de hecho, estoy conectadouniq -c.sort -uera parte de la 7ª Edición de UNIX, alrededor de 1979. Las versionessortsin soporte-uson 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 elipcomando ahora.uniq -c" (y tal vez canalizando una vez mássort -nr | head). Me preguntaba a qué equivalesort | uniqen Vim cuando descubrí que Vim tiene el:sort umando. Y TILsort -uexiste también.sort -n | uniqcontrasort -n -u. Por ejemplo, los espacios en blanco iniciales y finales serán vistos como duplicadossort -n -upor el primero, pero no por el primero.echo -e 'test \n test' | sort -n -uvuelvetest, peroecho -e 'test \n test' | sort -n | uniqdevuelve ambas líneas.Una diferencia es que
uniqtiene una serie de opciones adicionales útiles, como omitir campos para comparar y contar el número de repeticiones de un valor.sortLa-ubandera solo implementa la funcionalidad deluniqcomando sin adornos .fuente
sort -uNo se puede pasar la salida deuniqpara usar algunas de las opciones útiles de esta última, como omitir campos para comparar y contar el número de repeticiones".Con
sorts yuniqs compatibles con POSIX (GNUuniqactualmente no es compatible en ese sentido), hay una diferencia en quesortusa el algoritmo de clasificación de la configuración regional para comparar cadenas (generalmente se usarástrcoll()para comparar cadenas) mientras seuniqverifica 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 -ulo que retendría solo uno de cada uno, mientras que parauniq(no GNUuniqque usastrcoll()(excepto con-i)), ① es diferente de ② y 0123 es diferente de ٠١٢٣, poruniqlo que consideraría todos 4 únicos.strcollsolo 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 -uposible 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
uniqcompara la línea completa léxicamente, mientras quesortla-ucomparación se basa en la especificación de clasificación dada en la línea de comando.fuente
Prefiero usarlo
sort | uniqporque cuando trato de usar la-uopció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
-uopción para eliminar duplicados. Usaruniqes más predecible. Lo siguiente primero ordena e ignora el caso y luego lo pasauniqpara eliminar los duplicados.fuente
-uopción desortsalidas el primero de una ejecución igual (ver página de manual) Por lo tanto,sort -furecoge la primera aparición de cada línea única que no distingue entre mayúsculas y minúsculas. La lógica que sesortusa para eliminar duplicados es predecible.Otra diferencia que descubrí hoy es al ordenar en base a un delimitador donde se
sort -uaplica la bandera única solo en la columna con la que se ordena.fuente