Linux: awk

18. November 2023

awk ist ein mächtiges Kommandozeilenwerkzeug in Linux, das zum Verarbeiten und Manipulieren von Textdateien verwendet wird. Es liest Zeilen aus einer Datei, wendet bestimmte Aktionen auf die Zeilen an und gibt das Ergebnis aus. Nachfolgend sind einige grundlegende Konzepte aufgelistet, um einen ersten Überblick zu schaffen.

Grundstruktur

Die Grundstruktur folgt folgendem Prinzip: Klammern (wobei diese optional sind) mit einer Bedingung + geschwungene Klammern mit dem auszuführenden Code:

awk '($BEDINGUNG){print $0}'

# Alle Zeilen ausgeben, die mit cp beginnen
awk '($1=="cp"){print $0}' script.sh

Trennzeichen und Elemente

Das Standard-Trennzeichen ist ein Leerraum. Um diesen zu ändern gibt es die Option -F. Die Elemente sind mit $INDEX (Beginnend mit 1) abrufbar. $0 gibt die komplette Zeile zurück.

awk -F: '{print $1}' /etc/passwd

Hiermit wird die /etc/passwd Datei ausgelesen, pro Zeile die Elemente mittels : gesplittet und das erste Element (Benutzername) zurückgegeben.

Elemente ersetzen

Elemente können einfach ersetzt werden. Im folgenden Beispiel werden wird cp durch mv ersetzt.

awk '($1=="cp"){$1="mv"} {print $0}' script.sh

Code aus Datei lesen

Anstatt wie in den vorherigen Beispielen den Code (= der, der in einfachen Anführungszeichen steht) direkt in den Befehl zu schreiben, kann auf die option -f verwendet werden. Dies ist vor allem dann sinnvoll, wenn der Code größer wird.

# code.txt

($1=="cp") 
{
  $1="mv"
}

{
  print $0
}

Und zum Ausführen:

awk -f code.txt script.sh

Am Anfang/Ende einen zusätzlichen Text ausgeben

Mit den Schlüsselwörtern BEGIN und END können am Anfang bzw. am Ende zusätzliche Texte ausgegeben werden.

awk 'BEGIN {print "ANFANG"} {print $0} END {print "ENDE"}' script.sh

Arbeiten mit Variablen

In den Scripts können auch Variablen definiert werden. Im folgenden Beispiel werden die Zeilen gezählt und am Ende ausgegeben.

awk ‚{count++;print $0} END {print „Anzahl Zeilen: “ count}‘ script.sh

awk hat auch einige eingebaute Variablen. Hier ein kleiner Teil daraus.

NF = Anzahl der Felder in der aktuellen Zeile
NR = aktuell verarbeitete Zeile

Funktionen

Mit Hilfe von Funktionen können Elemente verändert werden.

int($1)       = Konvertierung des Elements in einen Integer
rand()        = Zufällige Zahl zwischen 0 und 0.999999...
length($1)    = gibt die Länge zurück
tolower($1)   = Umwandeln in Kleinbuchstaben
toupper($1)   = Umwandeln in Großbuchstaben

Es können auch eigene Funktionen definiert werden.

awk '
function test()
{
  return tolower($1)
}

{print test()}' script.sh

Weitere Beispiele

Zeilennummer ausgeben

awk '{print NR, $0}' script.sh

Filtern

# Zeilen, die muster enthalten
awk '/muster/ {print}' script.sh

# Zeilen, die muster nicht enhalten
awk '!/muster/ {print}' datei.txt

# Zeilen, die mit muster beginnen
awk '/^muster/ {print}' datei.txt

# Zeilen, die mit muster enden
awk '/muster$/ {print}' datei.txt

# Regex mit einem bestimmten Wert
ls -la | awk '$9 ~ /a/ {print}'
ls -la | awk '($9 ~ /a/ && $2 > 90) {print}'

# Regex ohne bestimmten Wert
ls -la | awk '$9 !~ /a/ {print}'

Leerzeilen entfernen

awk 'NF > 0' script.sh

Zeichen ersetzen

# ersetzt alle Vorkommen von cp durch mv
awk '{ gsub("cp", "mv"); print }' script.sh

# ersetzt alle Vorkommen von cp in Spalte 3 durch mv
awk '{ gsub("cp", "mv", $3); print }' script.sh

Alternativ steht die Methode „sub“ zur Verfügung, die nur das erste Vorkommen ersetzt.

Ausgabe der ersten und zweiten Spalte mit Komma als Trennzeichen

awk 'BEGIN{OFS=","} {print $1, $2}' datei.txt

Anderes Trennzeichen beim Einlesen verwenden

awk -F":" '{print $1}' /etc/passwd

Skript aus einer Datei anwenden

awk -f script.awk datei.txt

Dateien auflisten, durchnummerieren

ls -la | awk 'BEGIN{OFS=";"; count=0} ($1 ~ /^\-/) {count=count+1; print count, NR, $3, $9} END{print NF, FS, NR}'