|
Mojo_Dodo
Anmeldungsdatum: 31. Januar 2008
Beiträge: 212
|
Hallo zusammen,
da ich einige csv-Dateien auswerten muss, wollte ich mir mit awk das Leben etwas leichter machen, was bisher aber noch nicht ganz geklappt hat ☺ Ich habe mehrere csv-Dateien, welche alle folgendermaßen aufgebaut sind:
Datei1.csv | Spalte1,Spalte2,Spalte3
1,10.1,150
2,15.5,160
3,16.7,170
4,19.8,180
5,20.1,190
|
Nun muss ich für jede Datei von jeder Spalte den Mittelwert und die Standardabweichung berechnen und hätte die Ergebnisse gerne gesammelt in einer neuen Datei, z.B. so: | Dateiname,MW Spalte1,Stabw Spalte1,MW Spalte2,Stabw Spalte2,MW Spalte3,Stabw Spalte3
Datei1.csv,3.0,1.58,16.4,4.1,170.0,15.81
Datei2.csv,
Datei3.csv,
|
Ich habe so angefangen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | awk -F',' 'BEGIN { OFS = "," } {
for(i=1; i<=NF; i++)
{ sum[i] += $i;
}}
END {
{ OFS = "," }
for(i=1; i<=NF; i++){
mean = sum[i]/(NR);
if(i<NF){
printf mean
}else{
print mean}
};
}' Pfad/*.csv >> Pfad/Ergebnisse.csv
|
und habe dazu nun folgende Fragen:
Die Ausgabe in Zeilenform funktioniert bereits, aber es fehlen die Trennzeichen. Was habe ich mit OFS = "," falsch gemacht? Beim Berechnen des Mittelwerts nimmt awk die erste Zeile mit der Beschriftung als 0. Das lässt sich mit sum[i]/(NR-1) zwar beheben, aber gibt noch eine bessere Lösung dafür? Der awk-Befehl soll ja auf alle Dateien angewendet werden. Pfad/*.csv >> Pfad/Ergebnisse.csv führt aber nicht dazu, dass die Ausgabe der nächsten Datei in einer neuen Zeile landet. Das wollte ich erreichen indem ich am Ende print, anstatt printf genommen habe. Für die Standardabweichung bin ich mir sicher an welcher Stelle ich die Formel einfügen muss? Hinter sum[i] += $i; ist es ja noch nicht möglich, weil ich den Mittelwert noch nicht habe.
Über Hinweise jeglicher Art bin ich sehr dankbar! Es muss übrigens nicht unbedingt awk sein. Falls es sinnvoller ist, können auch alle anderen Bash-Bordmittel zum Einsatz kommen.
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
Ich bin nicht geübt mit awk, daher kommen sicher noch bessere Vorschläge - meinen ist mit gesundem Misstrauen zu begegnen. a) gehört das Script in eine Datei, etwa stdabw.awk:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | #!/usr/bin/awk
# usage: awk -F',' ' $0 FILE
#
BEGIN { OFS = "," } {
for(i=1; i<=NF; i++)
{
sum[i] += $i;
}
}
END {
{
OFS = ","
}
for(i=1; i<=NF; i++) {
mean = sum[i]/(NR);
if (i<NF) {
printf mean" "
} else {
print mean }
};
}
|
Der Shebang ist ungetestet, dem besonders misstrauen.
Das -F kann man bestimmt in den Beginn-Block integrieren. Multiple Dateien verarzten:
| for f in D*csv; do awk -F',' -f stdabw.awk $f ; done
2.5 13.7 141.667
2.5 13.7 141.667
|
Zweimal dasselbe, weil ich die Datei einfach kopiert habe. Dunkel erinnere ich mich, an eigenen Trouble mit OFS.
Das setzt manuell einen Trenner. Komma müsste auch funzen.
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
Nach kleinen Tests mit IFS, OFS und FS:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | BEGIN { FS=","} {
for(i=1; i<=NF; i++)
{
sum[i] += $i;
}
}
END {
for(i=1; i<=NF; i++) {
mean = sum[i]/(NR);
if (i<NF) {
printf mean", "
} else {
print mean
}
}
}
|
Aufruf dann:
| for f in D*csv; do awk -f stdabw.awk $f ; done
|
Und Ausgabe in Datei:
| for f in D*csv; do awk -f stdabw.awk $f ; done > Pfad/Ergebnisse.csv
|
|
|
Mojo_Dodo
(Themenstarter)
Anmeldungsdatum: 31. Januar 2008
Beiträge: 212
|
Zuerst mal vielen Dank für die Hilfe! Ich hab noch etwas rumprobiert und das Skript sieht nun so aus: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | BEGIN { FS="," } { OFS="," } {
for(i=1; i<=NF; i++)
{
sum[i] += $i;
}
}
END {
for(i=1; i<=NF; i++) {
mean = sum[i]/(NR-1);
if (i<NF) {
printf "%s%s", mean,OFS
} else {
print mean
}
}
}
|
Was ich nicht wusste: die Variablen OFS und ORS haben keinen Einfluss auf printf, sondern nur auf print - siehe hier im gawk manual: https://www.gnu.org/software/gawk/manual/html_node/Basic-Printf.html#Basic-Printf Ich habe es jetzt mit printf "%s%s", mean,OFS gelöst. d.h. in greife mit printf einfach auf die Variable OFS zurück. Es funktioniert, aber ob das der sinnvollste Weg ist, weiß ich nicht. Mal eine andere Frage: mit welchem Editor bekomme ich denn automatisch eine so übersichtliche Darstellung des Codes wie in dem oben geposteten Beispiel?
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
Mojo_Dodo schrieb: Mal eine andere Frage: mit welchem Editor bekomme ich denn automatisch eine so übersichtliche Darstellung des Codes wie in dem oben geposteten Beispiel?
Was meinst Du mit oben geposteten Beispiel?
|
|
Mojo_Dodo
(Themenstarter)
Anmeldungsdatum: 31. Januar 2008
Beiträge: 212
|
user_unknown schrieb: Mojo_Dodo schrieb: Mal eine andere Frage: mit welchem Editor bekomme ich denn automatisch eine so übersichtliche Darstellung des Codes wie in dem oben geposteten Beispiel?
Was meinst Du mit oben geposteten Beispiel?
Mein anfangs geposteter Code war nicht sehr übersichtlich formatiert. Die von dir korrigierte Variante hingegen schon. Hast du die geschweiften Klammern, usw. "manuell" übersichtlich eingerückt oder nutzt du einen Editor der das automatisch macht?
|
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17630
|
Das ist ja schon ne Woche her. Hab's wahrscheinlich in den Editor gepackt, um es einzurücken, um überhaupt die Struktur erkennen zu können. Da wohnt so ein Formatiertier in mir, das macht das schon halbautomatisch.
|