Linux: awk
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}'