awk – Spalten herausziehen und Summen bilden, direkt im Terminal
Wie viele Bytes hat mein Server heute ausgeliefert? Welche IP taucht am häufigsten im Log auf? Für solche Fragen muss man keine Datei herunterladen und in Excel öffnen – awk beantwortet sie in einer Zeile.
awk sieht auf den ersten Blick nach Hieroglyphen aus. Dabei muss man für 90 % der Fälle nur zwei Dinge wissen: $1, $2, $3 sind die Spalten einer Zeile, und was in geschweiften Klammern steht, passiert für jede Zeile.
# die dritte Spalte jeder Zeile ausgeben
awk '{ print $3 }' zugriffe.log$0 ist die ganze Zeile, NF die Anzahl der Spalten — $NF ist damit immer die letzte Spalte, egal wie viele es sind. Das brauche ich ständig.
Nur bestimmte Zeilen
Vor die Klammern kommt eine Bedingung:
# nur Zeilen mit Status 404, davon die angeforderte Adresse
awk '$9 == 404 { print $7 }' zugriffe.log
# nur Zeilen, die "error" enthalten
awk '/error/ { print }' app.logDas ersetzt schon mal ein grep davor.
Rechnen – der eigentliche Grund
Hier wird es interessant. awk merkt sich Werte über alle Zeilen hinweg und gibt am Ende (END) etwas aus:
# Summe der ausgelieferten Bytes (Spalte 10 im üblichen Logformat)
awk '{ summe += $10 } END { print summe/1024/1024 " MB" }' zugriffe.log
# Durchschnitt und Anzahl
awk '{ s += $10; n++ } END { printf "%d Zeilen, im Mittel %.1f Bytes\n", n, s/n }' zugriffe.logKein Skript, keine Zwischendatei. Eine Zeile.
Zählen und sortieren – mein meistgenutzter Einzeiler
# welche IP wie oft?
awk '{ anzahl[$1]++ } END { for (ip in anzahl) print anzahl[ip], ip }' zugriffe.log \
| sort -rn | head -10anzahl[$1]++ legt für jede IP einen Zähler an — awk hat assoziative Arrays eingebaut. Am Ende wird alles ausgegeben und mit sort -rn absteigend nach Zahl sortiert.
Denselben Einzeiler benutze ich für alles Mögliche: häufigste Fehlerseiten ($7 bei Status 404), häufigste Benutzer, häufigste Statuscodes. Nur der Spaltenindex ändert sich.
Ein anderes Trennzeichen
Standardmäßig trennt awk an Leerzeichen. Für CSV oder /etc/passwd sagt man es ihm:
# dritte Spalte aus einer semikolongetrennten Datei
awk -F';' '{ print $3 }' kunden.csv
# alle Benutzernamen mit UID über 1000
awk -F':' '$3 >= 1000 { print $1 }' /etc/passwdWichtig bei CSV: Das funktioniert nur, solange in keinem Feld ein Semikolon in Anführungszeichen steht. Für echtes, sauberes CSV-Parsing ist awk das falsche Werkzeug — dann nehme ich ein kleines Skript in PHP oder Python. Für Logdateien und einfache Exporte ist es perfekt.
Die Kopfzeile überspringen
awk -F';' 'NR > 1 { summe += $4 } END { print summe }' umsatz.csvNR ist die aktuelle Zeilennummer — NR > 1 lässt die Kopfzeile aus.
Warum ich das nicht durch ein Skript ersetze
Weil die Frage meistens einmalig ist. „Wie viele Zugriffe kamen gestern aus Deutschland?" beantwortet man einmal und will dafür keine Datei anlegen. awk ist genau für diese Sorte Frage gebaut — und die drei Bausteine oben ($n, Bedingung, END) decken fast alles davon ab.
Du hast Logdateien auf deinem Server, in die noch nie jemand geschaut hat? Da steht oft mehr drin, als man denkt. Schreib mir, wenn du dabei Unterstützung willst.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Dateirechte verstehen – was 755 und 644 wirklich bedeuten
chmod 777 löst jedes Rechteproblem – und schafft ein größeres. Die drei Ziffern sind kein Zauberspruch, sondern eine simple Addition. Wer sie einmal verstanden hat, rät nie wieder.
cron – Aufgaben, die von selbst laufen (und warum sie es oft nicht tun)
Nächtliches Backup, wöchentlicher Bericht, stündliche Bereinigung: Fünf Zahlen und ein Befehl reichen. Der häufigste Fehler ist dabei nicht die Zeitangabe, sondern eine Umgebung, die ganz anders aussieht als dein Terminal.
„Address already in use" – herausfinden, wer den Port belegt
Der Entwicklungsserver startet nicht, weil Port 8000 angeblich schon benutzt wird – meistens von einem eigenen Prozess von vorhin. Mit ss oder lsof findest du ihn in Sekunden, statt das Terminal neu zu starten.