EMZETT.
Login

Kurz: AWK nutzt erweiterte reguläre Ausdrücke (ERE). Sie stehen zwischen /…/, als Zeichenkette oder in einer Variablen:

Teil des Kurses AWK

Kapitel 6 von 8 im Kurs AWK. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Grundbausteine

AWK nutzt erweiterte reguläre Ausdrücke (ERE). Sie stehen zwischen /.../, als Zeichenkette oder in einer Variablen:

BEGIN {
    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
}

Ausgabe:

1
1 0 1
1
26 26 15
mia@example.com
17 Datum: ####-##-##, Mail: mia@example.com, Tel: +## ## #####
BausteinBedeutung
.beliebiges Zeichen
* + ?beliebig oft / mindestens einmal / optional
{n,m}n bis m Wiederholungen
[abc] [^abc] [a-z]Zeichenklassen
(a|b)Alternative
^ $Anfang/Ende
[[:alpha:]] [[:digit:]] [[:space:]]POSIX-Klassen
\\.maskierter Punkt (in Strings doppelt maskieren)

Mit Treffern arbeiten

Mit gawks match(string, regex, array) erhältst du Teiltreffer in Gruppen:

BEGIN {
    zeile = "192.168.0.15 - - [15/Mar/2024:14:30:00] \"GET /index.html HTTP/1.1\" 200 5120"
    if (match(zeile, /^([0-9.]+) .*\[([^\]]+)\] "([A-Z]+) ([^ ]+) [^"]*" ([0-9]+) ([0-9]+)/, g)) {
        print "IP:      ", g[1]
        print "Zeit:    ", g[2]
        print "Methode: ", g[3]
        print "Pfad:    ", g[4]
        print "Status:  ", g[5]
        print "Bytes:   ", g[6]
    }
    print gensub(/([0-9]+)\/([A-Za-z]+)\/([0-9]+)/, "\\3-\\2-\\1", "g", "15/Mar/2024")
    s = "Hallo Welt"
    print gensub(/(\w+) (\w+)/, "\\2 \\1", 1, s)
    print gensub(/o/, "0", "g", s)
    print gensub(/o/, "0", 2, s)
}

Ausgabe:

IP:       192.168.0.15
Zeit:     15/Mar/2024:14:30:00
Methode:  GET
Pfad:     /index.html
Status:   200
Bytes:    5120
2024-Mar-15
Welt Hallo
Hall0 Welt
Hallo Welt

Felder und Trenner als Regex

printf 'a1b22c333d\n' | awk -F'[0-9]+' '{ for (i = 1; i <= NF; i++) printf "[%s]", $i; print "" }'
printf 'a, b;c ,d\n' | awk -F' *[,;] *' '{ print NF; print $1 "|" $2 "|" $3 "|" $4 }'
printf 'ein   Wort\tund   mehr\n' | awk '{ print NF ": " $1 "-" $2 "-" $3 "-" $4 }'
printf 'key=value\n' | awk -F= '{ print $2 "=" $1 }'
printf 'x y z\n' | awk '{ $2 = "NEU"; print; print NF }'
printf 'x y z\n' | awk '{ $5 = "e"; print; print NF }'
printf 'a:b:c\n' | awk 'BEGIN { FS = ":"; OFS = "-" } { $1 = $1; print }'

Ausgabe:

[a][b][c][d]
4
a|b|c|d
4: ein-Wort-und-mehr
value=key
x NEU z
3
x y z  e
5
a-b-c

Weist du einem Feld etwas zu, baut AWK $0 mit OFS neu zusammen ($1 = $1 erzwingt das).

Typische Muster

function trim(s) { gsub(/^[ \t]+|[ \t]+$/, "", s); return s }
function ist_zahl(s) { return s ~ /^[-+]?[0-9]+(\.[0-9]+)?$/ }
function ist_email(s) { return s ~ /^[[:alnum:]._-]+@[[:alnum:].-]+\.[a-z]{2,}$/ }
function ist_ipv4(s,    p, i, n) {
    n = split(s, p, ".")
    if (n != 4) return 0
    for (i = 1; i <= 4; i++) if (p[i] !~ /^[0-9]+$/ || p[i] > 255) return 0
    return 1
}
 
BEGIN {
    print "[" trim("   mitte   ") "]"
    print ist_zahl("-12.5"), ist_zahl("12a"), ist_zahl("7")
    print ist_email("mia@example.com"), ist_email("kaputt@"), ist_email("a.b-c@x-y.org")
    print ist_ipv4("192.168.0.1"), ist_ipv4("256.1.1.1"), ist_ipv4("1.2.3")
    text = "Die Katze jagt die Maus. Die Maus flieht."
    anzahl = gsub(/[Dd]ie/, "&!", text)
    print anzahl, text
}

Ausgabe:

[mitte]
1 0 1
1 0 1
1 0 0
3 Die! Katze jagt die! Maus. Die! Maus flieht.

& steht in der Ersetzung für den gesamten Treffer.

Merke

  • AWK nutzt ERE: {n,m}, (a|b), [[:alpha:]]; Backslashes in Strings doppelt schreiben
  • gawk: match(s, re, arr) liefert Gruppen, gensub ersetzt mit Rückbezügen (\\1)
  • Der Feldtrenner -F darf ein Regex sein
  • & in sub/gsub steht für den ganzen Treffer

Übungsaufgabe

Zerlege eine Apache-Logzeile mit match in IP, Zeit und Statuscode.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Fortgeschrittene Techniken

Weiter: Praxisprojekte

Alle Kapitel: AWK im Überblick