Cómo agregar cada salida de awk

Cómo agregar cada salida de awk

¿Cómo realizarías la suma en la salida de cada línea de awk?

Por ejemplo

cat foo | awk '{print $1}
42
42
42

Estoy buscando la respuesta a 42+42+42 (126).

Estoy intentando escribir un bucle for para hacer esto, pero debe haber una forma más sencilla.

#Not Working, and way too complex
cat foo |awk  '{ print $1 }'|for i in $1 do; foo=$(( foo+$(i) )) done| echo $foo

Podría canalizar wc -lpero eso solo imprime el número de líneas, no las evalúa.

¿Cómo puedo evaluar cada línea de awk?

Respuesta1

Un enfoque básico, usando su ejemplo:

awk '{sum+=$1} END {print sum}' file

Respuesta2

Si tiene control sobre el programa awk, realice la adición dentro de awk como lo muestra @jasonwryan.

Si realmente desea resumir los números que arroja awk, canalice la salida a uno de estos:

| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }

En el segundo ejemplo, el comando echo está entre llaves de agrupación porque bash ejecuta la canalización en un subshell, por lo que los cambios en la variable $sum no existirán cuando el subshell salga.

Respuesta3

Bash no puede manejar decimales, pero puede manejar una manipulación simple de números enteros, solo necesitas usar un truco comosustitución de procesospara hacer que la variable sea accesible fuera del bucle:

n=0;while read i; do let n+=$i; done < <(awk '{print $1}' foo); echo $n;

o

n=0;while read i; do n=$((n+i)); done < <(awk '{print $1}' foo); echo $n;

Está n=0ahí solo para asegurarse de que $nsiempre sea 0; de lo contrario, ejecutar estos comandos por segunda vez devolvería 252 en lugar de 126.


Si bien la forma más sencilla sería usar gawkpara hacer el cálculo, también puedes usar una frase de Perl:

awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'

La -lbandera elimina las nuevas líneas ( chomp) y agrega una al final de cada cadena impresa, lo -nque significa leer el archivo línea por línea, guardar cada línea $_y ejecutar el script proporcionado con -e.

O haz todo en Perl:

perl -alne '$k+=$F[0];END{print "$k"};' foo

La -abandera de Perl activa la división automática de líneas (como gawk). De forma predeterminada, los campos están divididos en espacios, pero eso se puede cambiar usando -F. Los campos resultantes se guardan como @Fmatriz, por lo que el primer campo es $F[0].

Respuesta4

El método de una sola línea que suelo utilizar para totales simples como este es canalizar a xargs para obtener todos los resultados de awk en una línea, luego a través de sed para transformar espacios en pluses y, finalmente, a bc para hacer el cálculo:

cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc

información relacionada