Wir bezeichnen die Sprache als AWK und das ausführbare Programm, das AWK-Programme interpretiert, als awk oder gawk.
Ein AWK-Programm besteht aus Muster-Aktions-Paaren
pattern1 { action1 }
pattern2 { action2 }
...
Ein Muster kann ein regulärer Ausdruck sein, der auf die Eingabe angewendet wird. Es kann auch jeder Ausdruck sein, der einen Wahrheitswert ergibt.
Eine Aktion besteht aus einem oder mehreren AWK-Befehlen. Die umschließenden geschweiften Klammern sind erforderlich.
Wenn das Ergebnis des Musters wahr ist, wird die entsprechende Aktion ausgewertet.
AWK zerlegt die Eingabe in eine Folge von Datensätzen. Jeder Datensatz wird in null oder mehr Felder aufgeteilt.
Das Standardverhalten ist:
Das Muster kann weggelassen werden; in diesem Fall wird die Aktion für jeden Eingabedatensatz ausgewertet.
Die Aktion kann weggelassen werden; in diesem Fall besteht die Standardaktion darin, den aktuellen Datensatz auszugeben.
Es gibt zwei spezielle Muster, die häufig verwendet werden.
BEGIN wertet die zugehörige Aktion aus, bevor eine Eingabe verarbeitet wird.END wertet die zugehörige Aktion aus, nachdem die gesamte Eingabe verarbeitet wurde.Du verweist mit $1, $2, $3 usw. auf Felder.
Der aktuelle Datensatz ist $0.
Hier sind einige weitere häufig verwendete eingebaute Variablen.
RS ist das Datensatztrennzeichen der Eingabe.
Wie bereits erwähnt, ist sein Standardwert ein Zeilenumbruch.FS ist das Feldtrennzeichen der Eingabe.Diese Variablen werden oft im BEGIN-Aktionsblock gesetzt.
Diese Variablen werden von AWK während der Ausführung des Programms automatisch gesetzt.
NF speichert die Anzahl der Felder im aktuellen Datensatz.
$NF.NR speichert die aktuelle Datensatznummer.
NR die Gesamtzahl der bisher verarbeiteten Datensätze.FNR speichert die aktuelle Datensatznummer der aktuellen Eingabedatei.
NR == FNR {action}
Das bedeutet: „Wenn die akkumulierte Datensatznummer gleich der Datensatznummer der aktuellen Datei ist.“
Dies kann nur für Datensätze in der ersten Eingabedatei wahr sein.AWK verwendet dasselbe Konzept der Wahrheitswertigkeit wie C.
0 ist falsch.Da AWK eine textverarbeitende Sprache ist, werden Wahrheitswerte auf Strings erweitert.
"" ist falsch.Kommentare beginnen mit dem Zeichen # und reichen bis zum Ende der Zeile.
Auf Unix-ähnlichen Systemen enthält /etc/passwd Informationen über Benutzer.
Jeder Benutzer wird in einer separaten Zeile beschrieben, wobei die Felder durch Doppelpunkte getrennt sind.
Um die Benutzernamen aufzulisten:
awk '
BEGIN { FS = ":" }
{ print $1 }
' /etc/passwd
Beachte, dass die Aktion {print $1} kein Muster hat und daher für jeden Datensatz ausgeführt wird.
Wenn wir die Ausgabe auf Benutzer beschränken wollen, die bash als Login-Shell verwenden, können wir das so machen:
awk '
BEGIN { FS = ":" }
$7 == "/bin/bash" { print $1 }
' /etc/passwd
Es war einmal eine geschäftige Stadt namens Cyberspace. Cyberspace war eine digitale Metropole, in der sich jeden Tag Millionen von Bewohnern ein- und ausloggten. Um all diese Benutzer im Blick zu behalten, gab es in Cyberspace eine spezielle Datei namens /etc/passwd.
Die Datei /etc/passwd war wie ein Telefonbuch für die Stadt. Sie listete jeden Benutzer auf, der ein Konto auf dem System hatte, zusammen mit einigen wichtigen Informationen über jeden Benutzer:
| n | Feld |
|---|---|
| 1 | Benutzername |
| 2 | Passwort („x“ bedeutet, dass das eigentliche Passwort aus Sicherheitsgründen woanders gespeichert ist) |
| 3 | UID, eine eindeutige numerische Benutzer-ID |
| 4 | GID, eine eindeutige numerische Gruppen-ID (normalerweise dieselbe wie die UID) |
| 5 | Benutzerinfo (normalerweise der vollständige Name des Benutzers, kann aber weitere Informationen enthalten) |
| 6 | Home-Verzeichnis |
| 7 | Login-Shell |
Die Felder werden durch einen Doppelpunkt getrennt. Ein typischer Eintrag sieht so aus:
glennj:x:1010:1010:Glenn Jackman:/home/glennj:/usr/local/bin/fish
Die Datei wurde von einem Team von Systemadministratoren verwaltet, die dafür zuständig waren, neue Konten anzulegen, bestehende Konten zu aktualisieren und alte Konten zu entfernen. Die Systemadministratoren waren die Torwächter von Cyberspace und sorgten dafür, dass nur autorisierte Benutzer auf das System zugreifen konnten.
Eines Tages wurde ein neuer Systemadministrator namens Alex eingestellt, um das Team zu verstärken. Alex freute sich auf den Job und lernte schnell alle Feinheiten der Datei /etc/passwd kennen. Sie lernten, wie man neue Benutzer zum System hinzufügt, Benutzerinformationen aktualisiert und alte Benutzer entfernt.
Als Alex an der Datei /etc/passwd arbeitete, bemerkten sie etwas Seltsames. Einige Benutzer hatten seltsame oder ungewöhnliche Home-Verzeichnisse. Bei einigen Benutzern war das Home-Verzeichnis auf /dev/null gesetzt, bei anderen auf seltsame Pfade, die es gar nicht gab.
Alex erkannte, dass diese Benutzer keine echten Personen waren, sondern gefälschte Konten, die Hacker angelegt hatten. Die Hacker hatten einen Weg gefunden, eine Sicherheitslücke im System auszunutzen, und hatten diese gefälschten Konten angelegt, um sich Zugang zu Cyberspace zu verschaffen.
Alex wusste, dass sie handeln mussten. Sie nutzten awk, um die Datei /etc/passwd zu analysieren, und schrieben ein Skript, das alle gefälschten Konten aufspürte. Dann arbeiteten sie mit dem Rest des Teams zusammen, um diese Konten zu entfernen und die Sicherheitslücke zu schließen, die es den Hackern überhaupt erst ermöglicht hatte, sie anzulegen.
Dank Alex' Einsatz von awk konnte das Team die gefälschten Konten aufspüren und entfernen und Cyberspace für alle sicherer machen. Die Systemadministratoren verwalteten die Datei /etc/passwd weiter, hielten sie aktuell und sicher und sorgten dafür, dass nur autorisierte Benutzer auf das System zugreifen konnten.
Jetzt bist du an der Reihe: Werde ein Systemadministrator wie Alex.
Hier ist etwas zusätzliche AWK-Syntax, die du brauchst, um diese Übung zu lösen.
Boolesche Operatoren ähneln denen anderer Sprachen:
| Operation | Beispiel |
|---|---|
| AND | expr1 && expr2 |
| OR | expr1 || expr2 |
| NOT | ! expr |
Der Aufruf einer Funktion hat eine vertraute Syntax:
function greet(name) {
print "Hello", name
}
BEGIN {
greet("Mary") # prints "Hello Mary"
}
Schreibe ein awk-Programm, das für jede Zeile in der passwd-Datei das erste durch Doppelpunkte getrennte Feld ausgibt.
Schreibe einen awk-Befehl, der die Zeilennummer jedes Datensatzes in der Eingabedatei ausgibt. Gib nur die Zeilennummer aus, keine anderen Informationen.
In Cyberspace beginnt ein „gültiges“ Home-Verzeichnis mit /home oder /root.
Gib die Datensätze der Eingabedatei mit ungültigen Home-Verzeichnissen aus.
Gib die Datensätze aus, bei denen das Home-Verzeichnis gültig ist und die Login-Shell bash ist.
Melde dich bei Exercism an, um AWK mit 3 Konzepte92 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.