Kurz: Die eigentliche Stärke von AWK: Muster, die auf jede Zeile angewendet werden. Im Kurs erzeugen wir die Daten direkt im Beispiel (per printf und Pipe), wie man es auch in einem Shell-Skript tun würde.
Teil des Kurses AWK
Eingabe zeilenweise verarbeiten
Die eigentliche Stärke von AWK: Muster, die auf jede Zeile angewendet werden. Im Kurs erzeugen wir die Daten direkt im Beispiel (per printf und Pipe), wie man es auch in einem Shell-Skript tun würde.
printf 'Mia 17 Berlin\nTom 25 Hamburg\nZoe 31 Koeln\nBen 12 Berlin\n' | awk '
NR == 1 { print "Erste Zeile:", $0 }
$2 > 20 { print $1, "ist über 20" }
/Berlin/ { berlin++ }
END { print NR, "Zeilen,", berlin, "aus Berlin" }
'Ausgabe:
Erste Zeile: Mia 17 Berlin
Tom ist über 20
Zoe ist über 20
4 Zeilen, 2 aus BerlinMehrere Muster pro Programm sind erlaubt; trifft eine Zeile mehrere, laufen alle Aktionen nacheinander.
Spalten, Trenner und Formatierung
printf 'name;preis;menge\nApfel;1.20;10\nBirne;0.80;25\nKiwi;2.50;4\n' | awk -F';' '
BEGIN { OFS = " | " }
NR == 1 { print $1, $2, $3, "summe"; next }
{
summe = $2 * $3
gesamt += summe
printf "%-6s %6.2f %4d %8.2f\n", $1, $2, $3, summe
}
END { printf "Gesamt: %.2f\n", gesamt }
'Ausgabe:
name | preis | menge | summe
Apfel 1.20 10 12.00
Birne 0.80 25 20.00
Kiwi 2.50 4 10.00
Gesamt: 42.00next springt zur nächsten Zeile. Mit -F legst du den Feldtrenner fest, auch als Regex (-F'[,;]').
Muster-Bereiche und Bedingungen
printf 'a\nSTART\nb\nc\nEND\nd\n' | awk '/START/,/END/ { print NR ": " $0 }'
echo ---
printf '1\n2\n3\n4\n5\n6\n' | awk 'NR % 2 == 0'
echo ---
printf 'x 5\ny 15\nz 25\n' | awk '$2 >= 10 && $2 < 20'
echo ---
printf 'a b c\n\nd e\n' | awk 'NF { print NF ": " $0 }'
echo ---
printf 'eins\nzwei\ndrei\n' | awk 'END { print $0, NR }'Ausgabe:
2: START
3: b
4: c
5: END
---
2
4
6
---
y 15
---
3: a b c
2: d e
---
drei 3Mehrere Dateien und FILENAME
printf 'a\nb\n' > /tmp/awk-eins.txt
printf 'c\nd\ne\n' > /tmp/awk-zwei.txt
awk '{ print FILENAME ":" FNR ":" NR ": " $0 }' /tmp/awk-eins.txt /tmp/awk-zwei.txt
awk 'FNR == 1 { print "== " FILENAME " ==" } END { print NR " Zeilen insgesamt" }' /tmp/awk-eins.txt /tmp/awk-zwei.txt
rm /tmp/awk-eins.txt /tmp/awk-zwei.txtAusgabe:
/tmp/awk-eins.txt:1:1: a
/tmp/awk-eins.txt:2:2: b
/tmp/awk-zwei.txt:1:3: c
/tmp/awk-zwei.txt:2:4: d
/tmp/awk-zwei.txt:3:5: e
== /tmp/awk-eins.txt ==
== /tmp/awk-zwei.txt ==
5 Zeilen insgesamtAusgabe umleiten und Pipes
printf 'b 2\na 1\nc 3\n' | awk '{ print $1, $2 | "sort" } END { close("sort"); print "fertig" }'
printf '1\n2\n3\n' | awk '{ s += $1 } END { print "Summe:", s, "Mittel:", s / NR }'
printf 'x\n' | awk '{ print "auf stderr" > "/dev/stderr"; print "auf stdout" }' 2>/dev/null
printf 'ein Satz hier\n' | awk '{ for (i = NF; i >= 1; i--) printf "%s%s", $i, (i > 1 ? " " : "\n") }'Ausgabe:
a 1
b 2
c 3
fertig
Summe: 6 Mittel: 2
auf stdout
hier Satz einMerke
- Muster wählen Zeilen aus (Regex, Vergleich, Bereich
a,b), Aktionen verarbeiten sie -Fsetzt den Feldtrenner,OFSden Ausgabe-Trenner;nextüberspringt eine ZeileNRzählt über alle Dateien,FNRpro Datei;FILENAMEnennt die Datei- Ausgabe lässt sich mit
>und|umleiten (close()nicht vergessen)
Übungsaufgabe
Summiere die dritte Spalte einer CSV-Datei, gruppiert nach der ersten Spalte.
Quiz zur Selbstkontrolle
Was bewirkt next?
- Überspringt den Rest und liest die nächste Zeile (richtig)
- Beendet das Programm
- Springt zur letzten Zeile
- Wiederholt die Zeile
Was ist der Unterschied zwischen NR und FNR?
- NR zählt über alle Dateien, FNR pro Datei (richtig)
- Kein Unterschied
- NR ist ein Dateiname
- FNR ist die Feldzahl
Wie setzt man den Feldtrenner auf Semikolon?
- -F’;’ (richtig)
- -S ’;’
- —sep ’;’
- -d ’;‘
Weiter im Kurs
Zurück: Arrays und Zeichenketten
Weiter: Fortgeschrittene Techniken
Alle Kapitel: AWK im Überblick