2012-05-09 46 views
23

Mi file.txt se ve así:awk suma de una columna y la impresión que se suma, en cada línea de entrada

1 12 
2 18 
3 45 
4 5 
5 71 
6 96 
7 13 
8 12 

puedo resumir la segunda columna de la siguiente manera:

awk '{ sum += $2 } END { print sum }' file.txt

272

¿Cuál es la mejor manera que puedo imprimir esa suma en cada línea? Esto es lo que estoy esperando:

1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 
+0

Gracias a todos! Algunas respuestas muy útiles aquí. Aclamaciones. – Steve

Respuesta

19

tipo de forma estándar awk.

$ awk 'FNR==NR{sum+=$2;next}; {print $0,sum}' file.txt{,} 
1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 
+0

El sufijo de comodín '{,}' es una abreviatura para repetir el nombre del archivo de entrada dos veces. No es el shell Bourne estándar. – tripleee

+1

Esto es AWK canónico y no almacena el archivo en la memoria. Debe ser la respuesta aceptada. –

+0

@DennisWilliamson, Hola, ¿podría explicar por qué motivo este awk no almacena el archivo en la memoria?gracias –

1

Offtopic, pero en Perl que puede hacer:

perl -nale '$s+=$F[1];push(@a,$_);END{print $_." $s" for(@a);}' file.txt 
7

que puede utilizar:

awk -v xyzzy=$(awk '{sum+=$2}END{print sum}' file.txt) 
    '{print $0" "xyzzy}' file.txt 

Esto, desafortunadamente, significa ir a través de la información dos veces pero, como tiene que hacerlo una vez antes de obtener el total, no hay una forma real de evitarlo. Cualquier solución implicará almacenar la información antes de enviar cualquier cosa (ya sea en matrices o al volver al archivo).

El interior awk calcula el total y el exterior awk lo asigna a una variable que se puede imprimir junto con cada línea.

Aplicando que en el fichero:

a 1 
b 2 
c 3 
d 4 
e 5 

le da, porque 1 + 2 + 3 + 4 + 5 es igual a 15:

a 1 15 
b 2 15 
c 3 15 
d 4 15 
e 5 15 
+0

@codaddict: ¿quiso decir "... _ no puede almacenar ..."? – paxdiablo

+0

sí ... No sé qué pasó allí :) – codaddict

3

Usar grupos

{ 
    a[NR] = $0 
    sum += $2 
} 
END { 
    for (x = 1; x <= NR; x++) { 
     print a[x], sum 
    } 
} 

salida

$ awk -f s.awk file.txt 
1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 

leer más en Gnu Awk Manual

1

La solución fea:

awk '{printf "%s ", $0}{system(" awk \047 {sum+=$2}END{print sum} \047 file ")}' file 
1

awk, sí, la cabeza y pasta.

$ yes "`<file.txt awk '{ sum += $2 } END { print sum }'`" | head -n `<file.txt wc -l` | paste -d ' ' file.txt - 
Cuestiones relacionadas