2012-11-07 19 views
7

Ich habe 500 Dateien mit Namen fort.1, fort.2 ... fort.500. Jede Datei enthält 800 Daten wie folgt:Durchschnitt berechnen mit awk aus mehreren Dateien

1 0,485
2 0,028
3 0,100
4 0,979
5 0,338
6 0,891
7 0,415
8 0,368
9 0,245
10 0.489

Ich möchte den Durchschnitt jeder Zeile der zweiten Spalte aus jeder Datei erhalten. Mit anderen Worten, erhalte den Durchschnitt der zweiten Spalte der ersten Zeile von allen Dateien und speichere ihn in "output.file". Dann erhalten Sie den Durchschnitt der zweiten Spalte der zweiten Zeile und speichern Sie in der gleichen "output.file". Ich habe mit dem Befehl paste versucht, aber nicht bekommen, was ich will. Gibt es eine Möglichkeit, in AWK zu tun?

Schätzen Sie jede Hilfe. Danke

Antwort

1

Mein Verständnis: Jede Datei ist eine Reihe von Messungen an einem bestimmten Ort. Sie möchten die Messungen über alle Standorte hinweg aggregieren, indem Sie den Wert derselben Zeile in jeder Datei zu einer neuen Datei zusammenfassen.

die erste Spalte Unter der Annahme kann für die Zeile als ID behandelt werden (und es gibt 800 Messungen in einer Datei):

cat fort.* | awk ' 
BEGIN { 
    for (i = 1; i <= 800; i++) 
     total[i] = 0 
} 

{ total[$1] += $2 } 

END { 
    for (i = 1; i <= 800; i++) 
     print i, total[i]/500 
} 
' 

Zuerst initialisieren wir eine Anordnung, die Summe für eine Zeile über alle speichern Dateien.

Dann durchlaufen wir die verketteten Dateien. Wir verwenden die erste Spalte als Schlüssel für die Zeile und wir addieren sie in das Array.

Schließlich durchlaufen wir das Array und drucken den Durchschnittswert nach Zeilen über alle Dateien.

+0

In diesem Code, was ich verstehe, ist, dass zunächst alle Werte von fort.1 Datei im Array "total" behalten. Als nächstes geht es um die zweite Datei fort.2 zu lesen und im Array insgesamt zu halten. (Zum Beispiel), dann soll es (Gesamt [1] + Gesamt [1]/2) von erster und zweiter Datei jeweils tun, um den Durchschnitt zu erhalten. Aber ich verstehe das nicht ... Tut mir leid, wenn ich falsch verstanden habe. – Vijay

+0

Bearbeitet, um meine Annahmen um das Problem widerzuspiegeln. –

+0

Danke für Ihre schnelle Antwort. Lass mich nochmal klarstellen was ich will. Jede Datei (insgesamt 500 Dateien) enthält zwei Spalten (1. Spalte und 2. Spalte) und 800 Zeilen Zeilen.Ich möchte, dass die erste Zeile, die zweite Spalte jeder Datei (alle 500 Dateien) hinzugefügt wird und den Durchschnitt berechnet und in einer neuen Datei als Durchschnitt gespeichert wird. Dann geht es in die zweite Zeile, 2. Spalte aller Dateien (500 Dateien) und berechnen Sie den Durchschnitt und speichern Sie im Durchschnitt. Output. Und es wird fortgesetzt, bis die durchschnittliche output-Datei 800 Zeilen enthält. Ich wünsche Ihnen, dass Sie diese Erklärung erhalten. Entschuldigung, wenn meine Frage in der Post dich verwirrt hat. Vielen Dank im Voraus. – Vijay

2

die erste Spalte Unter der Annahme ist eine ID:

cat fort.* | awk '{sum[$1] += $2; counts[$1]++;} END {for (i in sum) print i, sum[i]/counts[i];}' 
5

Hier ist eine schnelle Art und Weise mit paste und awk:

paste fort.* | awk '{ for(i=2;i<=NF;i+=2) array[$1]+=$i; if (i = NF) print $1, array[$1]/NF*2 }' > output.file 

Wie einige der anderen Antworten; hier ist eine andere Art und Weise, aber dieses verwendet sort numerisch sortierte Ausgabe zu erhalten:

awk '{ sum[$1]+=$2; cnt[$1]++ } END { for (i in sum) print i, sum[i]/cnt[i] | "sort -n" }' fort.* 
7

awk ohne Annahme auf der 1. Säule:

awk '{a[FNR]+=$2;b[FNR]++;}END{for(i=1;i<=FNR;i++)print i,a[i]/b[i];}' fort.* 
+0

Berücksichtigt dieser Code alle "erste Zeile aller Eingabedateien (fort.1, fort.2 ...)" und berechnet den Durchschnitt und geht anschließend in die zweite Zeile aller Dateien (fort.1, fort.2 ...). .) bis 800 Zeilen aus jeder Datei? Ich brauche eine Erklärung, um zu verstehen, was dieser Code tatsächlich macht. Danke – Vijay

+0

@Vijay: In der Tat .. aktualisiert es mit dem Fort. *, Um es klarer zu machen. Sie können es gegen eine kleine Beispieldatei testen, um zu bestätigen ... – Guru

+0

Guru, Dieser Code funktioniert gut. Vielen Dank. Zusätzlich muss noch etwas hinzugefügt werden. Ich habe Dateien mit Namen for.1, fort.2 und so weiter. Ich fürchte, wenn ich Fort. * Setze, wird es Fort.1, Fort.10, Fort.100 statt Fort.1, Fort.2 und so weiter lesen. Wie kann das behandelt werden? Danke – Vijay

Verwandte Themen