2011-07-15 25 views

Respuesta

544

Suponiendo que hay un número por línea:

sort <file> | uniq -c 

puede utilizar la más prolija --count bandera también con la versión de GNU, por ejemplo, en Linux:

sort <file> | uniq --count 
+1

Esto es lo que hago sin embargo, 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 de gran tamaño, por lo que el rendimiento es un problema clave. Me pregunto si hay una herramienta que hace solo el recuento en una sola pasada usando un árbol de prefijos (en mi caso las cadenas a menudo tienen prefijos comunes) o similar, que debería hacer el truco en O (n) * avg_line_len. ¿Alguien conoce una herramienta de línea de comandos? – Droggl

+10

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 más a menudo. – samoz

+19

Si solo desea imprimir líneas duplicadas, use 'uniq -d' – DmitrySandalov

7

Suponiendo que tenga acceso a un shell de Unix estándar y/o el medio ambiente cygwin:

tr -s ' ' '\n' < yourfile | sort | uniq -d -c 
     ^--space char 

Básicamente: convertir todos los caracteres de espacio a los saltos de línea, luego clasifique la salida tranlsated y alimente eso a uniq y cuente las líneas duplicadas.

58

Para buscar y contar las líneas duplicadas en varios archivos, puede intentar el siguiente comando:

sort <files> | uniq -c | sort -nr 

o:

cat <files> | sort | uniq -c | sort -nr 
+7

+1 para mostrar las líneas más frecuentes en la parte superior –

282

Esto hará líneas duplicadas de impresión sólo, con recuentos:

sort FILE | uniq -cd 

o, con opciones largas de GNU (en Linux):

sort FILE | uniq --count --repeated 

en BSD and OSX you have to use grep para filtrar las líneas únicas:

sort FILE | uniq -c | grep -v '^ *1 ' 

Para el ejemplo dado, el resultado sería:

3 123 
    2 234 

Si desea recuentos de impresión para todas las líneas incluyendo aquellas que aparecen solo una vez:

sort FILE | uniq -c 

o, con opciones de GNU largos (en Linux):

sort FILE | uniq --count 

para la entrada dada, la salida es:

3 123 
    2 234 
    1 345 

Para ordenar la salida con las líneas más frecuentes en la parte superior, puede hacer lo siguiente (para obtener todos los resultados):

sort FILE | uniq -c | sort -nr 

o, para obtener sólo duplicar las líneas, más frecuentes primero:

sort FILE | uniq -cd | sort -nr 

en OSX y BSD la final se convierte en:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr 
+1

Buen punto con la opción --repetida o -d. ¡Mucho más preciso que usar "| grep 2" o similar! – Lauri

+0

¿Cómo puedo modificar este comando para recuperar todas las líneas cuyo recuento de repeticiones es más de 100? –

+0

@Black_Rider Agregar '| ordenar -n' o '| ordenar -nr' a la tubería clasificará la salida por conteo de repetición (ascendente o descendente, respectivamente). Esto no es lo que estás preguntando, pero pensé que podría ser útil. – Andrea

19

Via :

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data 

En el comando awk 'dups[$1]++', la variable $1 contiene todo el contenido de la columna1 y los corchetes son acceso a la matriz. Por lo tanto, para cada primera columna de línea en el archivo data, se incrementa el nodo de la matriz denominada dups.

Y al final, que se recorre durante dups matriz con num tan variables e imprimir los números guardados primeros entonces su número de valor duplicado por dups[num].

Tenga en cuenta que el archivo de entrada tiene espacios en el final de algunas líneas, si desaparecen los, se puede utilizar en lugar del $0$1 en comando anterior :)

+1

¿No es esto un poco excesivo teniendo en cuenta que tenemos 'uniq'? –

+6

'clasificación | uniq' y la solución awk tienen compensaciones de rendimiento y recursos bastante diferentes: si los archivos son grandes y la cantidad de líneas diferentes es pequeña, 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 líneas diferentes en la memoria, mientras que el género (GNU) puede recurrir a archivos temporales. –

7

En las ventanas usando "Windows PowerShell" Me utilizado el comando se menciona a continuación para lograr este

Get-Content .\file.txt | Group-Object | Select Name, Count 

también podemos usar el cmdlet donde a objetos para filtrar el resultado

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count 
+0

¿puedes eliminar todas las apariciones de los duplicados, excepto el último ... sin cambiar el orden de clasificación del archivo? – jparram

Cuestiones relacionadas