¿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 -l
pero 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=0
ahí solo para asegurarse de que $n
siempre 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 gawk
para hacer el cálculo, también puedes usar una frase de Perl:
awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'
La -l
bandera elimina las nuevas líneas ( chomp
) y agrega una al final de cada cadena impresa, lo -n
que 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 -a
bandera 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 @F
matriz, 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