Wie man die AWK-Sprache zum Manipulieren von Text in Linux verwendet

Einführung

Linux-Dienstprogramme folgen oft der Unix-Designphilosophie. Es wird empfohlen, dass Tools klein sind, einfache Textdateien für Ein- und Ausgabe verwenden und modular arbeiten. Aufgrund dieses Erbes verfügen wir über eine großartige Textverarbeitungsfunktionalität mit Tools wie sed und awk.

awk ist sowohl eine Programmiersprache als auch ein Textprozessor, den Sie verwenden können, um Textdaten auf sehr nützliche Weise zu manipulieren. In diesem Leitfaden werden Sie erfahren, wie Sie das Befehlszeilentool awk verwenden und wie Sie es zur Textverarbeitung einsetzen können.

Grundlegende Syntax

Der Befehl awk ist standardmäßig in allen modernen Linux-Systemen enthalten, sodass Sie ihn nicht installieren müssen, um ihn zu verwenden.

awk ist am nützlichsten beim Umgang mit Textdateien, die auf vorhersehbare Weise formatiert sind. Es ist beispielsweise ausgezeichnet beim Analysieren und Manipulieren tabellarischer Daten. Es arbeitet zeilenweise und iteriert durch die gesamte Datei.

Standardmäßig verwendet es Leerzeichen (Leerzeichen, Tabulatoren usw.), um Felder zu trennen. Glücklicherweise verwenden viele Konfigurationsdateien auf Ihrem Linux-System dieses Format.

Das Grundformat eines awk-Befehls ist:

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

Sie können entweder den Suchteil oder den Aktionsabschnitt aus jedem awk-Befehl weglassen. Standardmäßig wird die Aktion, wenn der „Aktions“-Abschnitt nicht angegeben ist, als „drucken“ ausgeführt. Dies druckt einfach alle Zeilen, die übereinstimmen.

Wenn der Suchteil nicht angegeben wird, führt awk die aufgeführte Aktion in jeder Zeile aus.

Wenn beide angegeben sind, verwendet awk den Suchteil, um zu entscheiden, ob die aktuelle Zeile dem Muster entspricht, und führt dann die Aktionen bei Übereinstimmungen aus.

In seiner einfachsten Form können Sie awk wie cat verwenden, um alle Zeilen einer Textdatei auf dem Bildschirm auszugeben.

Erstellen Sie eine favorite_food.txt-Datei, die die Lieblingsessen einer Gruppe von Freunden auflistet:

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

Verwenden Sie jetzt den awk-Befehl, um die Datei auf dem Bildschirm auszugeben:

  1. awk '{print}' favorite_food.txt

Sie werden die Datei auf dem Bildschirm sehen:

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

Dies ist nicht sehr nützlich. Lassen Sie uns die Suchfilterfähigkeiten von awk ausprobieren, indem Sie die Datei nach dem Text „Sand“ durchsuchen:

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

Wie Sie sehen können, druckt awk jetzt nur die Zeilen, die die Zeichen „Sand“ enthalten.

Mit regulären Ausdrücken können Sie bestimmte Teile des Textes anvisieren. Um nur die Zeile anzuzeigen, die mit den Buchstaben „Sand“ beginnt, verwenden Sie den regulären Ausdruck ^Sand:

  1. awk '/^sand/' favorite_food.txt

Diesmal wird nur eine Zeile angezeigt:

Output
sandwich brian

Ebenso können Sie den Aktionsabschnitt verwenden, um anzugeben, welche Informationen Sie drucken möchten. Um beispielsweise nur die erste Spalte zu drucken, verwenden Sie den folgenden Befehl:

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

Sie können jede Spalte (wie durch Leerzeichen getrennt) über Variablen, die mit ihrer Spaltennummer verknüpft sind, referenzieren. Zum Beispiel ist die erste Spalte $1, die zweite ist $2, und Sie können die gesamte Zeile mit $0 referenzieren.

Interne Variablen und erweiterndes Format

Der awk-Befehl verwendet einige interne Variablen, um bestimmte Informationen zuzuweisen, während er eine Datei verarbeitet.

Die internen Variablen, die awk verwendet, sind:

  • FILENAME: Verweist auf die aktuelle Eingabedatei.
  • FNR: Verweist auf die Nummer des aktuellen Datensatzes relativ zur aktuellen Eingabedatei. Wenn Sie zum Beispiel zwei Eingabedateien haben, würde dies Ihnen die Datensatznummer jeder Datei anzeigen, anstatt als Gesamtanzahl.
  • FS: Der aktuelle Feldseparator, der verwendet wird, um jedes Feld in einem Datensatz zu kennzeichnen. Standardmäßig ist dies auf Leerzeichen eingestellt.
  • NF: Die Anzahl der Felder im aktuellen Datensatz.
  • NR: Die Nummer des aktuellen Datensatzes.
  • OFS: Der Feldseparator für die ausgegebenen Daten. Standardmäßig ist dies auf Leerzeichen eingestellt.
  • ORS: Der Datensatzseparator für die ausgegebenen Daten. Standardmäßig handelt es sich dabei um ein Zeilenumbruchszeichen.
  • RS: Das Trennzeichen, das verwendet wird, um separate Datensätze in der Eingabedatei zu unterscheiden. Standardmäßig handelt es sich dabei um ein Zeilenumbruchszeichen.

Sie können die Werte dieser Variablen beliebig ändern, um sie an die Anforderungen Ihrer Dateien anzupassen. Normalerweise tun Sie dies während der Initialisierungsphase Ihrer Verarbeitung.

Dies bringt uns zu einem weiteren wichtigen Konzept. Die Syntax von awk ist etwas komplexer als das, was Sie bisher verwendet haben. Es gibt auch optionale BEGIN– und END-Blöcke, die Befehle enthalten können, die vor und nach der Dateiverarbeitung ausgeführt werden sollen.

Dies macht unsere erweiterte Syntax ungefähr wie folgt aussehen:

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

Die Schlüsselwörter BEGIN und END sind spezifische Bedingungssets, genau wie die Suchparameter. Sie entsprechen Bedingungen, die vor und nach der Dokumentverarbeitung erfüllt werden müssen.

Dies bedeutet, dass Sie einige der internen Variablen im BEGIN-Abschnitt ändern können. Zum Beispiel ist die Datei /etc/passwd durch Doppelpunkte (:) statt durch Leerzeichen begrenzt.

Um die erste Spalte dieser Datei auszudrucken, führen Sie den folgenden Befehl aus:

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

Sie können die BEGIN– und END-Blöcke verwenden, um Informationen über die Felder, die Sie drucken, auszugeben. Verwenden Sie den folgenden Befehl, um die Daten aus der Datei in eine Tabelle umzuwandeln, die schön mit Tabs formatiert ist, indem Sie \t verwenden:

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

Sie werden diese Ausgabe sehen:

Output
User UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete

Wie Sie sehen können, können Sie die Dinge recht ordentlich formatieren, indem Sie einige der Funktionen von awk nutzen.

Jeder der erweiterten Abschnitte ist optional. Tatsächlich ist der Hauptaktionsabschnitt selbst optional, wenn ein anderer Abschnitt definiert ist. Sie können zum Beispiel Dinge wie folgt tun:

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

Und Sie werden diese Ausgabe sehen:

Output
We can use awk like the echo command

Jetzt sehen wir uns an, wie man nach Text in Feldern der Ausgabe sucht.

Feldsuche und zusammengesetzte Ausdrücke

In einem der vorherigen Beispiele haben Sie die Zeile in der Datei favorite_food.txt gedruckt, die mit „sand“ begann. Dies war einfach, weil Sie nach dem Anfang der gesamten Zeile gesucht haben.

Was ist, wenn Sie herausfinden möchten, ob ein Suchmuster am Anfang eines Feldes übereinstimmt?

Erstellen Sie eine neue Version der Datei favorite_food.txt, die vor jedem Essen einer Person eine Artikelnummer hinzufügt:

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

Wenn Sie alle Lebensmittel aus dieser Datei finden möchten, die mit „sa“ beginnen, könnten Sie versuchen, etwas wie folgt zu tun:

  1. awk '/sa/' favorite_food.txt

Dies zeigt alle Zeilen an, die „sa“ enthalten:

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

Hier werden alle Instanzen von „sa“ im Wort abgeglichen. Dies schließt Dinge wie „Wasabi“ ein, das das Muster in der Mitte hat, oder „sandig“, das nicht in der Spalte ist, die Sie möchten. In diesem Fall interessieren Sie sich nur für Wörter, die mit „sa“ in der zweiten Spalte beginnen.

Sie können awk anweisen, nur am Anfang der zweiten Spalte zu übereinstimmen, indem Sie diesen Befehl verwenden:

  1. awk '$2 ~ /^sa/' favorite_food.txt

Wie Sie sehen können, ermöglicht uns dies, nur am Anfang der zweiten Spalte nach einer Übereinstimmung zu suchen.

Der Teil field_num ~ gibt an, dass awk nur auf die zweite Spalte achten sollte.

Output
3 sandwich brian 4 salad ryan

Sie können genauso leicht nach Dingen suchen, die nicht übereinstimmen, indem Sie das „!“ Zeichen vor der Tilde (~) einbeziehen. Dieser Befehl gibt alle Zeilen zurück, die kein Lebensmittel enthalten, das mit „sa“ beginnt:

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

Wenn Sie später feststellen, dass Sie nur an Zeilen interessiert sind, die nicht mit „sa“ beginnen und die Artikelnummer kleiner als 5 ist, könnten Sie einen zusammengesetzten Ausdruck wie diesen verwenden:

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

Dies führt einige neue Konzepte ein. Das erste ist die Möglichkeit, zusätzliche Anforderungen für das Übereinstimmen der Zeile durch Verwendung des && Operators hinzuzufügen. Damit können Sie eine beliebige Anzahl von Bedingungen kombinieren, damit die Zeile übereinstimmt. In diesem Fall verwenden Sie diesen Operator, um eine Überprüfung hinzuzufügen, dass der Wert der ersten Spalte kleiner als 5 ist.

Sie werden diese Ausgabe sehen:

Output
1 carrot sandy 2 wasabi luke

Sie können awk verwenden, um Dateien zu verarbeiten, aber Sie können auch mit der Ausgabe anderer Programme arbeiten.

Verarbeitung von Ausgaben anderer Programme

Sie können das awk-Befehl verwenden, um die Ausgabe anderer Programme zu analysieren, anstatt einen Dateinamen anzugeben. Zum Beispiel können Sie awk verwenden, um die IPv4-Adresse aus dem ip-Befehl zu extrahieren.

Der Befehl ip a zeigt die IP-Adresse, die Broadcast-Adresse und andere Informationen zu allen Netzwerkschnittstellen auf Ihrem Rechner an. Um die Informationen für die Schnittstelle namens eth0 anzuzeigen, verwenden Sie diesen Befehl:

  1. ip a s eth0

Sie sehen dann die folgenden Ergebnisse:

Output
2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

Sie können awk verwenden, um die Zeile inet zu zielen und dann nur die IP-Adresse auszugeben:

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

Die -F-Flag sagt awk, dass die Trennung durch Schrägstriche oder Leerzeichen mit dem regulären Ausdruck [\/ ]+ erfolgen soll. Dadurch werden die Zeile inet 172.17.0.11/16 in separate Felder aufgeteilt. Die IP-Adresse befindet sich im dritten Feld, da die Leerzeichen am Anfang der Zeile ebenfalls als Feld zählen, da Sie auch durch Leerzeichen sowie Schrägstriche begrenzt haben. Beachten Sie, dass awk in diesem Fall aufeinanderfolgende Leerzeichen als einzelnes Leerzeichen behandelt hat.

Die Ausgabe zeigt die IP-Adresse:

Output
172.17.0.11

Sie werden viele Stellen finden, an denen Sie awk verwenden können, um die Ausgabe anderer Befehle zu durchsuchen oder zu analysieren.

Abschluss

Bis jetzt sollten Sie ein grundlegendes Verständnis dafür haben, wie Sie den awk-Befehl verwenden können, um Textdateien und Textströme zu manipulieren, zu formatieren und selektiv auszugeben. Awk ist jedoch ein viel größeres Thema und ist tatsächlich eine komplette Programmiersprache mit Variablendeklaration, Kontrollstrukturen, integrierten Funktionen und mehr. Sie können es in Ihren eigenen Skripten verwenden, um Text auf zuverlässige Weise zu formatieren.

Um mehr über awk zu erfahren, können Sie das kostenlose Buch der Schöpfer im öffentlichen Bereich lesen, das viel detaillierter darauf eingeht.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-the-awk-language-to-manipulate-text-in-linux