Textverarbeitung in der Kommandozeile mit Mustern und Aktionen
Ausführen: Datei skript.awk speichern und mit awk -f skript.awk datei.txt ausführen; einfache Programme direkt als awk '{print $1}' datei.txt.
muster { aktion }; BEGIN und END laufen davor/danach$1, $2, ... zerlegt, NF und NR zählenprint und printf geben aus, Variablen brauchen keine Deklarationawk 'BEGIN { print "Hallo" }' # Programm direkt, ohne Eingabe
awk '{ print $1 }' datei.txt # erste Spalte jeder Zeile
awk -f skript.awk datei.txt # Programm aus Datei
awk -F, '{ print $2 }' daten.csv # Feldtrenner Komma
echo "a b c" | awk '{ print $2 }' # aus einer Pipeif/else, ?:, for, while, do für den Ablauf~ und !~function; lokale Variablen als Extra-ParameterBEGIN {
print 7 + 2, 7 - 2, 7 * 2, 7 / 2, 7 % 3, 2 ^ 10, 2 ** 3
a = 5; a += 3; a *= 2; print a
i = 1; i++; ++i; print i
print (3 < 5), (3 == 3), (3 != 3), ("a" < "b")
print (1 && 0), (1 || 0), !1
print "Text" " " "wird" " " "verkettet"
s = "abc"; print s s
print 1 " " 2
print 10 / 3
printf "%.2f\n", 10 / 3
print int(3.99), int(-3.99)
print sqrt(16), exp(0), log(1), sin(0), cos(0)
print length("hallo")
print 1e3, 0x10, 010
}in, delete, length(array) und asorti (gawk) erleichtern die Arbeitzaehler[schluessel]++ zählt und gruppiertsub, gsub, match, split, substr, sprintf sind die wichtigsten Textfunktionen/.../ und werden mit ~ geprüftBEGIN {
alter["Mia"] = 17
alter["Tom"] = 25
alter["Zoe"] = 31
print alter["Tom"], length(alter)
if ("Mia" in alter) print "Mia vorhanden"
if (!("Ben" in alter)) print "Ben fehlt"
delete alter["Tom"]
n = asorti(alter, namen)
for (i = 1; i <= n; i++) printf "%s=%d ", namen[i], alter[namen[i]]
print ""
zahlen[1] = "eins"; zahlen[2] = "zwei"; zahlen[3] = "drei"
for (i = 1; i <= length(zahlen); i++) printf "%s ", zahlen[i]
print ""
# mehrdimensional: Schlüssel mit SUBSEP
m[1,2] = "x"; m[2,1] = "y"
PROCINFO["sorted_in"] = "@ind_str_asc"
for (k in m) { split(k, t, SUBSEP); printf "(%d,%d)=%s ", t[1], t[2], m[k] }
print ""
delete m
print length(m)
}a,b), Aktionen verarbeiten sie-F setzt den Feldtrenner, OFS den Ausgabe-Trenner; next überspringt eine ZeileNR zählt über alle Dateien, FNR pro Datei; FILENAME nennt die Datei> und | umleiten (close() nicht vergessen)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" }
'.awk-Dateien mit Shebang #!/usr/bin/awk -fPROCINFO["sorted_in"] steuert die Schleifenreihenfolge (gawk)asort, gensub, strftime, Bit-Funktionen und mehrdimensionale Arrays!gesehen[$0]++ ist der bekannte Einzeiler gegen Duplikate#!/usr/bin/awk -f
# Bericht über Verkäufe
BEGIN {
FS = ","
daten = "Nord,100\nSued,250\nNord,50\nWest,75\nSued,25"
n = split(daten, zeilen, "\n")
for (i = 1; i <= n; i++) {
split(zeilen[i], f, ",")
summe[f[1]] += f[2]
anzahl[f[1]]++
}
PROCINFO["sorted_in"] = "@val_num_desc"
for (r in summe)
printf "%-6s Summe %4d Anzahl %d Mittel %.1f\n", r, summe[r], anzahl[r], summe[r] / anzahl[r]
}{n,m}, (a|b), [[:alpha:]]; Backslashes in Strings doppelt schreibenmatch(s, re, arr) liefert Gruppen, gensub ersetzt mit Rückbezügen (\\1)-F darf ein Regex sein& in sub/gsub steht für den ganzen TrefferBEGIN {
t = "Datum: 2024-03-15, Mail: mia@example.com, Tel: +49 30 12345"
print (t ~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)
print (t ~ /^Datum/), (t ~ /Tel$/), (t ~ /Tel: \+49/)
muster = "[a-z]+@[a-z]+\\.com"
print (t ~ muster)
print match(t, /[a-z]+@[a-z]+\.[a-z]+/), RSTART, RLENGTH
print substr(t, RSTART, RLENGTH)
n = gsub(/[0-9]/, "#", t)
print n, t
}-F,, Arrays und printfPROCINFO["sorted_in"] macht Berichte deterministisch<<'LOG') lassen sich Beispieldaten direkt im Skript mitgebencat > /tmp/awk-access.log <<'LOG'
10.0.0.1 - - [15/Mar/2024:10:00:01] "GET /index.html HTTP/1.1" 200 5120
10.0.0.2 - - [15/Mar/2024:10:00:05] "GET /bild.png HTTP/1.1" 200 20480
10.0.0.1 - - [15/Mar/2024:10:01:10] "GET /fehlt HTTP/1.1" 404 512
10.0.0.3 - - [15/Mar/2024:10:02:00] "POST /login HTTP/1.1" 302 0
10.0.0.2 - - [15/Mar/2024:10:03:30] "GET /index.html HTTP/1.1" 200 5120
LOG
awk '
{
status[$9]++
bytes += $10
pfad[$7]++
ip[$1]++
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
print "Statuscodes:"
for (s in status) printf " %s: %d\n", s, status[s]
PROCINFO["sorted_in"] = "@val_num_desc"
print "Meistbesucht:"
for (p in pfad) { printf " %s (%d)\n", p, pfad[p]; if (++n >= 2) break }
printf "Übertragen: %.1f KB in %d Anfragen\n", bytes / 1024, NR
printf "Verschiedene IPs: %d\n", length(ip)
}' /tmp/awk-access.log
rm /tmp/awk-access.logBEGIN {
srand(1)
zufall = rand()
print (zufall >= 0 && zufall < 1)
print ENVIRON["HOME"] != ""
print "Zeichen:", sprintf("%c%c%c", 76, 111, 76)
cmd = "echo hallo"
cmd | getline ausgabe
close(cmd)
print "Befehl lieferte:", ausgabe
print system("exit 3")
printf "%s %s\n", "a", "b"
printf "%5.1f%%\n", 99.5
}