¿Existe alguna solución mejor para imprimir líneas únicas que no sea una combinación de sort
y uniq
?
command-line
text-processing
Déjame ser
fuente
fuente
sort
(por ejemplo, GNU coreutils) usan archivos temporales y mergesort externo si la entrada es demasiado grande para caber en la RAM. Y la mayoría de las otras versiones tienen una-m
opción para que esto se pueda hacer explícitamente fragmentando la entrada (por ejemplo, consplit
), clasificando cada fragmento y luego fusionando los fragmentosRespuestas:
Para imprimir cada línea idéntica solo una, en cualquier orden:
Para imprimir solo las líneas únicas, en cualquier orden:
Para imprimir cada línea idéntica solo una vez, en el orden de su primera aparición: (para cada línea, imprima la línea si aún no se ha visto, luego, en cualquier caso, incremente el contador visto)
Para imprimir solo las líneas únicas, en el orden de su primera aparición: (registre cada línea en
seen
, y tambiénlines
si es la primera aparición; al final de la entrada, imprima las líneas en orden de aparición pero solo las que se ven solo una vez)fuente
awk '!seen[$0]++ {print}'
?awk '!seen[$0]++'
, ya que{print}
está implícito en un comando vacío.Algunas versiones (¿la mayoría?)
sort
Tienen una-u
bandera que hace launiq
parte directamente. Sin embargo, podría haber algunas restricciones de longitud de línea dependiendo de la implementación, pero ya las tenía con plainsort|uniq
.fuente
sort -u
vuelve al menos a V7.-u
pero también tienen una restricción de longitud de línea de 512 caracteres. (En realidad, creo que en algún lugar alrededor de Solaris 9 Sun aumentó a 5120. GNU todavía gana, sin embargo.)¿Perl trabaja para ti? Puede mantener las líneas en el orden original, incluso si los duplicados no son adyacentes. También puede codificarlo en Python, o
awk
.Que se puede acortar a solo
Archivo de entrada dado:
Produce la salida:
fuente
use strict;
ouse warnings;
(en realidad, esstrict
lo más relevante aquí), no hay ninguna queja sobre el uso%lines
antes de que se defina. Si se ejecuta con restricciones, debe haber una líneamy %lines;
antes del bucle. Tenga en cuenta también que el hash es%lines
; Se hace referencia a un elemento del hash utilizando la$lines{$_}
notación.sort
soluciones pueden ser mejores para una gran cantidad de datos (el OP estaba preocupado por "almacenar todo el archivo en la memoria").sort
realizará una ordenación fuera del núcleo si los datos son más grandes que la memoria disponible.Para la última parte de la respuesta mencionada en: Imprimir líneas únicas de @Gilles como respuesta a esta pregunta, traté de eliminar la necesidad de usar dos hashes.
Esta solución es para: Imprimir solo las líneas únicas, en el orden de su primera aparición:
awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'
Aquí, "contador" almacena un recuento de cada línea que es similar a la procesada anteriormente.
Al final, imprimimos solo aquellas líneas, que tienen un valor de contador como 1.
fuente