Ich habe eine Datei mit mehreren Tags mit einer Nummer daneben, z. B.
<Overall>4
other <tags> and data
<Overall>2
other <tags> and data
<Overall>3
Wie kann ich die Datei durchsuchen und alle Zahlen neben dem Gesamt-Tag zusammenzählen? Und dann die Zahl durch die Anzahl der Gesamt-Tags teilen, um einen Gesamtdurchschnitt zu erhalten.
Im obigen Code wäre der Durchschnitt beispielsweise 3.
Und durchlaufen Sie dann alle Dateien im aktuellen Verzeichnis und listen Sie den Gesamtdurchschnitt für jede Datei auf.
Antwort1
Verwenden von awk (vorausgesetzt, in den Gesamtzeilen steht nur das und eine Zahl)
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print "AVG:",y/x}' file
x wird für jedes erfolgreiche Sub von <Overall>
mit nichts erhöht. Dies bedeutet, dass es nur bei Zeilen erhöht wird, die enthalten <Overall>
.
Der folgende Block addiert dann die in der Zeile verbleibende Zahl zur Gesamtsumme.
END
wird am Ende des Programms ausgeführt.
Im Endblock wird der Durchschnitt ausgedruckt.
EDIT: für viele Dateien
awk 'x+=sub(/<Overall>/,""){y+=$0}END{print FILENAME,"AVG:",y/x}' LISTOFFILES
Antwort2
Mit perl
:
perl -lne 'for (/<Overall>([\d.eE+-]+)/g) {$n++; $sum += $1}
END{print $sum/$n if $n}'
Dies hat den Vorteil, dass mehr als ein Tag pro Zeile verarbeitet werden kann <Overall>
. [\d.eE+-]+
ist ein einfacher Matcher für eine Gleitkomma-Dezimalzahl (erlaubt Dinge wie 12, 1,2, -1E+20 (aber auch Dinge, die keine gültigen Zahlen sind)).
Antwort3
Hier ist eine grobe Methode in awk:
awk '/^<Overall>/ {
sub("<Overall>", "");
sum += $1;
lines++;
}
END { print sum / lines}'
tags ### this is your input file
Antwort4
Hier ist eine Lösung mit ein paar praktischen Dienstprogrammen:
grep "^<Overall>\d\+" file | cut -c 10 | paste -s -d + - | bc
- Durchsuchen Sie die Datei nach Zeilen, die mit „<Overkill>“ beginnen, gefolgt von einer Ziffernfolge (also einer Zahl).
- Schneiden Sie die Zahl aus dem Rest der Zeile aus.
- Verketten Sie alle Zeilen mit einem "+"-Symbol dazwischen
- Übergeben Sie das Ergebnis an
bc
, das die Summe berechnet