Esto es lo que hago, pero algorítmicamente este no parece ser el enfoque más eficiente (O (n log n) * avg_line_len donde n es el número de líneas). Estoy trabajando en archivos de varios gigabytes, por lo que el rendimiento es un problema clave. Me pregunto si hay una herramienta que solo cuente en una sola pasada usando un árbol de prefijos (en mi caso, las cadenas a menudo tienen prefijos comunes) o similar, eso debería ser el truco en O (n) * avg_line_len. ¿Alguien sabe una herramienta de línea de comandos?
Droggl
21
Un paso adicional es canalizar la salida de eso en un comando final 'sort -n'. Eso ordenará los resultados por los cuales las líneas ocurren con mayor frecuencia.
samoz
79
Si solo desea imprimir líneas duplicadas, use 'uniq -d'
DmitrySandalov
66
Si desea ordenar nuevamente el resultado, puede usarlo sortnuevamente como:sort <file> | uniq -c | sort -n
Abhishek Kashyap
414
Esto imprimirá solo líneas duplicadas , con recuentos:
Buen punto con la opción --repetido o -d. ¡Mucho más preciso que usar "| grep 2" o similar!
Lauri
¿Cómo puedo modificar este comando para recuperar todas las líneas cuyo recuento de repetición es superior a 100?
Black_Rider
@Black_Rider Agregar | sort -no | sort -nra la tubería ordenará la salida por recuento de repeticiones (ascendente o descendente, respectivamente). Esto no es lo que estás preguntando, pero pensé que podría ayudar.
Andrea
1
@Black_Rider awk parece capaz de hacer todo tipo de cálculos: en su caso, podría hacerlo| awk '$1>100'
awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data
En awk 'dups[$1]++'comando, la variable $1contiene todo el contenido de la columna 1 y los corchetes son acceso a la matriz. Entonces, para cada 1ra columna de línea en el dataarchivo, el nodo de la matriz nombrada dupsse incrementa.
Y al final, estamos recorriendo una dupsmatriz con una numvariable e imprimimos primero los números guardados y luego su número de valores duplicados dups[num].
Tenga en cuenta que su archivo de entrada tiene espacios al final de algunas líneas, si las borra, puede usarlas $0en lugar del $1comando anterior :)
¿No es esto un poco exagerado teniendo en cuenta que tenemos uniq?
Nathan Fellman
99
sort | uniqy la solución awk tiene compensaciones de rendimiento y recursos bastante diferentes: si los archivos son grandes y el número de líneas diferentes es pequeño, la solución awk es mucho más eficiente. Es lineal en el número de líneas y el uso del espacio es lineal en el número de líneas diferentes. OTOH, la solución awk necesita mantener todas las diferentes líneas en la memoria, mientras que la clasificación (GNU) puede recurrir a archivos temporales.
Lars Noschinski
14
En Windows usando "Windows PowerShell" usé el comando mencionado a continuación para lograr esto
Básicamente: convierta todos los caracteres de espacio en saltos de línea, luego ordene la salida traducida y aliméntela a uniq y cuente las líneas duplicadas.
Respuestas:
Suponiendo que haya un número por línea:
También puede usar el
--count
indicador más detallado con la versión GNU, por ejemplo, en Linux:fuente
sort
nuevamente como:sort <file> | uniq -c | sort -n
Esto imprimirá solo líneas duplicadas , con recuentos:
o, con las opciones largas de GNU (en Linux):
en BSD y OSX debe usar grep para filtrar líneas únicas:
Para el ejemplo dado, el resultado sería:
Si desea imprimir recuentos para todas las líneas, incluidas las que aparecen solo una vez:
o, con las opciones largas de GNU (en Linux):
Para la entrada dada, la salida es:
Para ordenar la salida con las líneas más frecuentes en la parte superior, puede hacer lo siguiente (para obtener todos los resultados):
o, para obtener solo líneas duplicadas, las más frecuentes primero:
en OSX y BSD el último se convierte en:
fuente
| sort -n
o| sort -nr
a la tubería ordenará la salida por recuento de repeticiones (ascendente o descendente, respectivamente). Esto no es lo que estás preguntando, pero pensé que podría ayudar.| awk '$1>100'
sort FILE | uniq -c | grep -v '^ *1 '
Para buscar y contar líneas duplicadas en varios archivos, puede probar el siguiente comando:
o:
fuente
Vía awk:
En
awk 'dups[$1]++'
comando, la variable$1
contiene todo el contenido de la columna 1 y los corchetes son acceso a la matriz. Entonces, para cada 1ra columna de línea en eldata
archivo, el nodo de la matriz nombradadups
se incrementa.Y al final, estamos recorriendo una
dups
matriz con unanum
variable e imprimimos primero los números guardados y luego su número de valores duplicadosdups[num]
.Tenga en cuenta que su archivo de entrada tiene espacios al final de algunas líneas, si las borra, puede usarlas
$0
en lugar del$1
comando anterior :)fuente
uniq
?sort | uniq
y la solución awk tiene compensaciones de rendimiento y recursos bastante diferentes: si los archivos son grandes y el número de líneas diferentes es pequeño, la solución awk es mucho más eficiente. Es lineal en el número de líneas y el uso del espacio es lineal en el número de líneas diferentes. OTOH, la solución awk necesita mantener todas las diferentes líneas en la memoria, mientras que la clasificación (GNU) puede recurrir a archivos temporales.En Windows usando "Windows PowerShell" usé el comando mencionado a continuación para lograr esto
También podemos usar el cmdlet where-object para filtrar el resultado
fuente
Suponiendo que tiene acceso a un entorno estándar de shell y / o cygwin de Unix:
Básicamente: convierta todos los caracteres de espacio en saltos de línea, luego ordene la salida traducida y aliméntela a uniq y cuente las líneas duplicadas.
fuente