2011-05-18 22 views
38

Dado un archivo de entrada que contiene un solo número por línea, ¿cómo podría obtener un recuento de cuántas veces se produjo un elemento en ese archivo?generar histograma desde el archivo

cat input.txt 
1 
2 
1 
3 
1 
0 

salida deseada (=> [1,3,1,1]):

cat output.txt 
0 1 
1 3 
2 1 
3 1 

Sería muy bueno, si la solución también podría extenderse para los números flotantes.

+2

Este tipo de producción es simple y útil, pero no es un histograma.Ver, por ejemplo, http://quarknet.fnal.gov/toolkits/ati/histograms.html –

Respuesta

69

¿Quiere decir que desea contar cuántas veces aparece un elemento en el archivo de entrada? Primero ordénelo (usando -n si la entrada es siempre números como en su ejemplo) y luego cuente los resultados únicos.

sort -n input.txt | uniq -c 
+2

No sabía sobre el comando 'uniq'. Lo cambié a 'cat input.txt | ordenar -n | uniq -c | awk '{print $ 2 "" $ 1}' ', ahora estoy obteniendo el resultado deseado. – Javier

+6

Su uso de awk para obtener el pedido está bien, pero no necesita usar un gato allí. Debería aprender sobre el operador '<' para ingresar archivos en programas e incluso cosas como construcciones de bucle. Para obtener información sobre el humor, vea [el uso inútil de premios de gato] (http://partmaps.org/era/unix/award.html#cat) – Caleb

0

Al menos algunos de los que se puede hacer con

sort output.txt | uniq -c 

Pero el orden se invierte number count. Esto solucionará ese problema.

sort test.dat | uniq -c | awk '{print $2, $1}' 
+0

Si los artículos de la columna uno tienen longitudes diferentes, esto arruinará la alineación a poco para que pueda usar una pestaña en lugar del espacio predeterminado cuando reordena las columnas: 'sort test.dat | uniq -c | awk '{print $ 2 "\ t" $ 1}' ' – PeterVermont

10

Otra opción:

awk '{n[$1]++} END {for (i in n) print i,n[i]}' input.txt | sort -n > output.txt 
+1

@Javier, la' n 'matriz simplemente cuenta las cadenas que ve en el archivo de entrada. Puede ser int, float o cualquier cadena arbitraria. Sí, la parte 'END' se ejecuta después de que el archivo de entrada se haya leído completamente. No necesita inicializar variables en awk: una variable no inicializada se considera cero o la cadena vacía (depende del contexto). En este caso, 'i' es una variable de bucle. Creo que el comportamiento predeterminado de 'clasificación' es considerar toda la línea. Esta solución funcionará para cualquier cosa en el archivo de entrada: las matrices awk son matrices asociativas. –

+1

gracias por ilutrasting una solución 'awk-based'. Por lo que entendí, en la primera parte almacenas el 'histograma' en la matriz' n' considerando los elementos en la columna '$ 1'. La parte 'END 'significa, que se va a hacer' después' del histograma, ¿verdad? ¿No es necesario inicializar la variable 'i' para bucles en' awk'? Entonces, el 'sort -n' se aplicará solo en la primera columna de la salida:' i, n [i] ', ¿no? es decir, no en 'n [i]'? Además, esta solución solo funcionaría para números 'enteros '(debido a la indexación de la matriz)? – Javier

+0

gracias por las claras explicaciones! – Javier

-1
perl -lne '$h{$_}++; END{for $n (sort keys %h) {print "$n\t$h{$n}"}}' input.txt 

bucle sobre cada línea con -n
Cada número $_ incrementos de hash %h
Una vez que la haya alcanzado END de input.txt,
sort el hash numéricamente
Imprimir el número $n y la frecuencia $h{$n}

Código similar que funciona en coma flotante:

perl -lne '$h{int($_)}++; END{for $n (sort keys %h) {print "$n\t$h{$n}"}}' float.txt 

float.txt

1.732 
2.236 
1.442 
3.162 
1.260 
0.707 

de salida:

0  1 
1  3 
2  1 
3  1 
0

Usando maphimbu del Debianstda paquete:

# use 'jot' to generate 100 random numbers between 1 and 5 
# and 'maphimbu' to print sorted "histogram": 
jot -r 100 1 5 | maphimbu -s 1 

Salida:

   1    20 
      2    21 
      3    20 
      4    21 
      5    18 

maphimbu también trabaja con coma flotante:

jot -r 100.0 10 15 | numprocess /%10/ | maphimbu -s 1 

Salida:

   1    21 
      1.1    17 
      1.2    14 
      1.3    18 
      1.4    11 
      1.5    19