EMZETT.
Login

Kurz: Jedes AWK-Array ist ein assoziatives Array (Schlüssel → Wert):

Teil des Kurses AWK

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

Assoziative Arrays

Jedes AWK-Array ist ein assoziatives Array (Schlüssel → Wert):

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

Ausgabe:

25 3
Mia vorhanden
Ben fehlt
Mia=17 Zoe=31
eins zwei drei
(1,2)=x (2,1)=y
0

Die Reihenfolge von for (k in array) ist unbestimmt. Für eine feste Ordnung nutzt man asort/asorti (gawk) oder sortiert die Ausgabe mit sort.

Zählen und Gruppieren

Das klassische AWK-Muster: Werte pro Schlüssel summieren.

BEGIN {
    text = "rot blau rot gruen blau rot"
    n = split(text, w, " ")
    for (i = 1; i <= n; i++) zaehler[w[i]]++
    m = asorti(zaehler, schluessel)
    for (i = 1; i <= m; i++) printf "%s: %d\n", schluessel[i], zaehler[schluessel[i]]
 
    umsatz["Nord"] += 100; umsatz["Sued"] += 250; umsatz["Nord"] += 50
    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (r in umsatz) printf "%-5s %6.2f\n", r, umsatz[r]
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (r in umsatz) { print "Spitzenreiter:", r; break }
}

Ausgabe:

blau: 2
gruen: 1
rot: 3
Nord  150.00
Sued  250.00
Spitzenreiter: Sued

Zeichenketten-Funktionen

BEGIN {
    s = "Hallo AWK Welt"
    print length(s), toupper(s), tolower(s)
    print substr(s, 7), substr(s, 7, 3)
    print index(s, "AWK")
    t = s; sub(/AWK/, "gawk", t); print t
    u = "a-b-c-d"; n = gsub(/-/, "+", u); print u, n
    v = "Preis: 42 EUR"; match(v, /[0-9]+/); print RSTART, RLENGTH, substr(v, RSTART, RLENGTH)
    n = split("a,b,,d", teile, ","); print n, teile[1], teile[3] "|", teile[4]
    n = split("2024-05-17", d, "-"); print d[3] "." d[2] "." d[1]
    print sprintf("%05.1f|%-6s|%6s|%x|%c", 3.14159, "li", "re", 255, 65)
    print gensub(/([0-9]+)-([0-9]+)/, "\\2-\\1", "g", "12-34 56-78")
    print strtonum("0x1F"), strtonum("017")
}

Ausgabe:

14 HALLO AWK WELT hallo awk welt
AWK Welt AWK
7
Hallo gawk Welt
a+b+c+d 3
8 2 42
4 a | d
17.05.2024
003.1|li    |    re|ff|A
34-12 78-56
31 15

Reguläre Ausdrücke

BEGIN {
    n = split("alice@example.com bob@test.org kein-mail", w, " ")
    for (i = 1; i <= n; i++) {
        if (w[i] ~ /^[a-z]+@[a-z]+\.[a-z]+$/) print w[i], "gültig"
        else print w[i], "ungültig"
    }
    text = "Telefon 030-12345 oder 040-98765"
    while (match(text, /[0-9]+-[0-9]+/)) {
        print substr(text, RSTART, RLENGTH)
        text = substr(text, RSTART + RLENGTH)
    }
    print ("abc123" ~ /[0-9]{3}$/), ("ab" ~ /^(a|b)+$/), ("x" ~ /^[^a-c]$/)
    print ("Hallo" ~ /hallo/), (tolower("Hallo") ~ /hallo/)
    IGNORECASE = 1
    print ("Hallo" ~ /hallo/)
}

Ausgabe:

alice@example.com gültig
bob@test.org gültig
kein-mail ungültig
030-12345
040-98765
1 1 1
0 1
1

Merke

  • Arrays sind assoziativ; in, delete, length(array) und asorti (gawk) erleichtern die Arbeit
  • Das Muster zaehler[schluessel]++ zählt und gruppiert
  • sub, gsub, match, split, substr, sprintf sind die wichtigsten Textfunktionen
  • Reguläre Ausdrücke stehen zwischen /.../ und werden mit ~ geprüft

Übungsaufgabe

Zähle die Buchstaben eines Textes und gib sie sortiert aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Variablen, Ausdrücke und Kontrollfluss

Weiter: Dateien, Spalten und Berichte

Alle Kapitel: AWK im Überblick