Tengo un archivo de texto con 2 millones de líneas. Cada línea tiene un entero positivo. Estoy tratando de formar un tipo de tabla de frecuencias.
Fichero de entrada:
3
4
5
8
La salida debe ser:
3
7
12
20
¿Cómo voy a hacer esto?
command-line
text-processing
Monty Harder
fuente
fuente
Respuestas:
Con
awk
:$0
Es la línea actual. Entonces, para cada línea, lo agrego atotal
, establezco la línea en la nuevatotal
, y luego el final1
es un atajo awk: imprime la línea actual para cada condición verdadera, y1
como condición se evalúa como verdadera.fuente
print
puede usar la palabra también?print total}
lugar de$0 = total}1
{print(total += $0)}
En un script de python:
Usar
add_last.py
Ejecútelo con el archivo de origen y el archivo de salida de destino como argumentos:
Explicación
El código es bastante legible, pero en detalle:
Abrir archivo de salida para escribir resultados
Abrir archivo de entrada para leer por línea
Lea las líneas y agregue el valor de la nueva línea al total:
Escriba el resultado en el archivo de salida:
fuente
Solo por diversión
Esto funciona mediante una pendiente
+p
a cada línea de la entrada, y luego pasando el resultado a ladc
calculadora dondeentonces
El
-e0
argumento empuja0
a ladc
pila para inicializar la suma.fuente
real 0m4.234s
En Bash:
fuente
real 0m53.116s
casi un minuto, en 1.3 millones de líneas :)Para imprimir sumas parciales de enteros dados en la entrada estándar, uno por línea:
Ejemplo ejecutable .
Si por alguna razón el comando es demasiado lento; podrías usar el programa C:
Para construirlo y ejecutarlo, escriba:
Ejemplo ejecutable .
UINTMAX_MAX
es18446744073709551615
.El código C es varias veces más rápido que el comando awk en mi máquina para el archivo de entrada generado por:
fuente
accumulate()
itertoolProbablemente quieras algo como esto:
Explicación del comando:
sort -n <filename> | uniq -c
ordena la entrada y devuelve una tabla de frecuencias| awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
convierte la salida en un formato más agradableEjemplo:
archivo de entrada
list.txt
:El comando:
fuente
Puedes hacer esto en vim. Abra el archivo y escriba las siguientes teclas:
Tenga en cuenta que en
<C-a>
realidad es ctrl-a, y<cr>
es retorno de carro , es decir, el botón enter.Así es como funciona esto. En primer lugar, queremos borrar el registro 'a' para que no tenga efectos secundarios la primera vez. Esto es simplemente
qaq
. Luego hacemos lo siguiente:Después de que esta macro recursiva haya terminado de ejecutarse, simplemente llamamos
:wq<cr>
para guardar y salir.fuente
Perl one-liner:
Con 2.5 millones de líneas de números, el procesamiento tarda aproximadamente 6.6 segundos:
fuente
real 0m0.908s
, muy agradable.Un simple Bash de una sola línea:
x
es la suma acumulada de todos los números de la línea actual y superior.n
es el número en la línea actual.Nos bucle sobre todas las líneas
n
deINPUT_FILE
y añadir su valor numérico para la variablex
e imprimir esa suma durante cada iteración.Sin embargo, Bash es un poco lento aquí, puede esperar que esto se ejecute alrededor de 20-30 segundos para un archivo con 2 millones de entradas, sin imprimir el resultado en la consola (que es aún más lento, independientemente del método que utilice).
fuente
Similar a la respuesta de @ steeldriver, pero con un poco menos arcano en su
bc
lugar:Lo bueno de
bc
(ydc
) es que son calculadoras de precisión arbitrarias, por lo que nunca se desbordarán ni sufrirán falta de precisión sobre los enteros.La
sed
expresión transforma la entrada en:Esto luego es evaluado por
bc
. Laa
variable bc se inicializa automáticamente a 0. Cada línea se incrementaa
, luego la imprime explícitamente.fuente
real 0m5.642s
en 1.3 millones de líneas. sed es muy lento en esto.