
Tengo un archivo con varias etiquetas con un número al lado, por ejemplo
<Overall>4
other <tags> and data
<Overall>2
other <tags> and data
<Overall>3
¿Cómo buscaría en el archivo y contaría todos los números junto a la etiqueta general? y luego divida el número por el número de etiquetas generales para obtener un promedio general.
Entonces, por ejemplo, en el código anterior, el promedio sería 3.
Y luego recorra todos los archivos en el directorio actual y enumere el promedio general de cada archivo.
Respuesta1
Usando awk (asumiendo que todo lo que está en las líneas generales es eso y un número)
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print "AVG:",y/x}' file
x se incrementa por cada subscripción exitosa <Overall>
sin nada. Esto significa que sólo se incrementa en las líneas que contienen <Overall>
.
El bloque posterior suma el número que queda en la línea al total.
END
se ejecuta al final del programa.
En el bloque final se imprime el promedio.
EDITAR: para muchos archivos
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print FILENAME,"AVG:",y/x}' LISTOFFILES
Respuesta2
Con perl
:
perl -lne 'for (/<Overall>([\d.eE+-]+)/g) {$n++; $sum += $1}
END{print $sum/$n if $n}'
Esto tiene la ventaja de poder manejar más de una <Overall>
etiqueta por línea. [\d.eE+-]+
es un comparador burdo para un número decimal de punto flotante (que permite cosas como 12, 1.2, -1E+20 (aunque también cosas que no son números válidos)).
Respuesta3
Aquí hay una forma cruda en awk:
awk '/^<Overall>/ {
sub("<Overall>", "");
sum += $1;
lines++;
}
END { print sum / lines}'
tags ### this is your input file
Respuesta4
Aquí hay una solución que utiliza algunas utilidades ingeniosas:
grep "^<Overall>\d\+" file | cut -c 10 | paste -s -d + - | bc
- Busque en el archivo líneas que comiencen con "<Overkill>" seguidas de una cadena de dígitos (es decir, un número).
- Recorta el número del resto de la línea.
- Concatena todas las líneas con un símbolo "+" en el medio
- Pase el resultado a
bc
, que calculará la suma.