GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Erweitern Sie Ihre awk-Fähigkeiten mit zwei einfachen Tutorials

Awk ist eines der ältesten Tools in der Werkzeugkiste der Unix- und Linux-Benutzer. awk wurde in den 1970er Jahren von Alfred Aho, Peter Weinberger und Brian Kernighan (das A, W und K des Namens des Tools) entwickelt und wurde für die komplexe Verarbeitung von Textströmen entwickelt. Es ist ein Begleitwerkzeug zu sed, dem Stream-Editor, der für die zeilenweise Verarbeitung von Textdateien entwickelt wurde. Awk ermöglicht komplexer strukturierte Programme und ist eine vollständige Programmiersprache.

Dieser Artikel erklärt, wie man awk für strukturiertere und komplexere Aufgaben verwendet, einschließlich einer einfachen Seriendruckanwendung.

Awk-Programmstruktur

Ein awk-Skript besteht aus funktionalen Blöcken, die von {} umgeben sind (geschweifte Klammern). Es gibt zwei spezielle Funktionsblöcke, BEGIN und ENDE , die vor der Verarbeitung der ersten Zeile des Eingabestreams und nach der Verarbeitung der letzten Zeile ausgeführt werden. Dazwischen haben Blöcke das Format:

pattern { action statements }

Jeder Block wird ausgeführt, wenn die Zeile im Eingabepuffer mit dem Muster übereinstimmt. Wenn kein Muster enthalten ist, wird der Funktionsblock auf jeder Zeile des Eingabestroms ausgeführt.

Außerdem kann die folgende Syntax verwendet werden, um Funktionen in awk zu definieren, die von jedem Block aus aufgerufen werden können:

function name(parameter list) { statements }

Diese Kombination aus Mustervergleichsblöcken und -funktionen ermöglicht es dem Entwickler, awk-Programme für Wiederverwendung und Lesbarkeit zu strukturieren.

Wie awk Textstreams verarbeitet

Awk liest Text aus seiner Eingabedatei oder streamt Zeile für Zeile und verwendet ein Feldtrennzeichen, um ihn in eine Reihe von Feldern zu zerlegen. In awk-Terminologie ist der aktuelle Puffer ein Datensatz . Es gibt eine Reihe spezieller Variablen, die beeinflussen, wie awk eine Datei liest und verarbeitet:

  • FS (Feldtrennzeichen):Standardmäßig ist dies ein beliebiges Leerzeichen (Leerzeichen oder Tabulatoren)
  • RS (Datensatztrennzeichen):Standardmäßig wird ein Zeilenumbruch (\n )
  • NF (Anzahl der Felder):Wenn awk eine Zeile parst, wird diese Variable auf die Anzahl der geparsten Felder gesetzt
  • $0: Der aktuelle Rekord
  • 1 $, 2 $, 3 $ usw.: Das erste, zweite, dritte usw. Feld aus dem aktuellen Datensatz
  • NR (Anzahl der Datensätze):Die Anzahl der Datensätze, die bisher vom awk-Skript geparst wurden

Es gibt viele andere Variablen, die das Verhalten von awk beeinflussen, aber das reicht für den Anfang.

Awk-Einzeiler

Bei einem so mächtigen Tool ist es interessant, dass awk hauptsächlich aus einfachen Einzeilern besteht. Das vielleicht gebräuchlichste awk-Programm druckt ausgewählte Felder aus einer Eingabezeile aus einer CSV-Datei, einer Protokolldatei usw. Zum Beispiel druckt der folgende Einzeiler eine Liste von Benutzernamen aus /etc/passwd :

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

Wie oben erwähnt, $1 ist das erste Feld im aktuellen Datensatz. Das -F Option setzt die FS-Variable auf das Zeichen : .

Der Feldtrenner kann auch in einem BEGIN-Funktionsblock gesetzt werden:

awk 'BEGIN { FS=":" } {print $1 }' /etc/passwd

Im folgenden Beispiel jeder Benutzer, dessen Shell nicht /sbin/nologin ist kann gedruckt werden, indem dem Block eine Musterübereinstimmung vorangestellt wird:

awk 'BEGIN { FS=":" } ! /\/sbin\/nologin/ {print $1 }' /etc/passwd

Erweitertes awk:Seriendruck

Nachdem Sie nun einige der Grundlagen kennen, versuchen Sie, mit einem strukturierteren Beispiel tiefer in awk einzutauchen:Erstellen eines Seriendrucks.

Ein Seriendruck verwendet zwei Dateien, eine (in diesem Beispiel mit dem Namen email_template.txt ) mit einer Vorlage für eine E-Mail, die Sie senden möchten:

From: Program committee <[email protected]>
To: {firstname} {lastname} <{email}>
Subject: Your presentation proposal

Dear {firstname},

Thank you for your presentation proposal:
  {title}

We are pleased to inform you that your proposal has been successful! We
will contact you shortly with further information about the event
schedule.

Thank you,
The Program Committee

Und die andere ist eine CSV-Datei (mit dem Namen proposals.csv ) mit den Personen, an die Sie die E-Mail senden möchten:

firstname,lastname,email,title
Harry,Potter,[email protected],"Defeating your nemesis in 3 easy steps"
Jack,Reacher,[email protected],"Hand-to-hand combat for beginners"
Mickey,Mouse,[email protected],"Surviving public speaking with a squeaky voice"
Santa,Claus,[email protected],"Efficient list-making"

Sie möchten die CSV-Datei lesen, die relevanten Felder in der ersten Datei ersetzen (die erste Zeile überspringen) und das Ergebnis dann in eine Datei namens acceptanceN.txt schreiben , Inkrementieren von N für jede Zeile, die Sie analysieren.

Schreiben Sie das awk-Programm in eine Datei namens mail_merge.awk . Anweisungen werden durch ; getrennt in awk-Skripten. Die erste Aufgabe besteht darin, die Feldtrennervariable und einige andere Variablen festzulegen, die das Skript benötigt. Sie müssen auch die erste Zeile in der CSV-Datei lesen und verwerfen, oder es wird eine Datei erstellt, die mit Dear firstname beginnt . Verwenden Sie dazu die Spezialfunktion getline und setzt den Datensatzzähler nach dem Lesen auf 0 zurück.

BEGIN {
  FS=",";
  template="email_template.txt";
  output="acceptance";
  getline;
  NR=0;
}

Die Hauptfunktion ist sehr einfach:Für jede verarbeitete Zeile wird eine Variable für die verschiedenen Felder gesetzt – firstname , Nachname , E-Mail , und Titel . Die Vorlagendatei wird zeilenweise gelesen und die Funktion sub wird verwendet, um jedes Vorkommen der Sonderzeichenfolgen durch den Wert der entsprechenden Variablen zu ersetzen. Dann wird die Zeile mit allen vorgenommenen Ersetzungen in die Ausgabedatei ausgegeben.

Da Sie es mit der Vorlagendatei und einer anderen Ausgabedatei für jede Zeile zu tun haben, müssen Sie die Dateihandles für diese Dateien bereinigen und schließen, bevor Sie den nächsten Datensatz verarbeiten.

{
        # Read relevant fields from input file
        firstname=$1;
        lastname=$2;
        email=$3;
        title=$4;

        # Set output filename
        outfile=(output NR ".txt");

        # Read a line from template, replace special fields, and
        # print result to output file
        while ( (getline ln < template) > 0 )
        {
                sub(/{firstname}/,firstname,ln);
                sub(/{lastname}/,lastname,ln);
                sub(/{email}/,email,ln);
                sub(/{title}/,title,ln);
                print(ln) > outfile;
        }

        # Close template and output file in advance of next record
        close(outfile);
        close(template);
}

Sie sind fertig! Führen Sie das Skript in der Befehlszeile aus mit:

awk -f mail_merge.awk proposals.csv

oder

awk -f mail_merge.awk < proposals.csv

und Sie finden Textdateien, die im aktuellen Verzeichnis generiert wurden.

Erweitertes awk:Worthäufigkeitszählung

Eines der mächtigsten Features in awk ist das assoziative Array. In den meisten Programmiersprachen werden Array-Einträge normalerweise durch eine Zahl indiziert, aber in awk werden Arrays durch eine Schlüsselzeichenfolge referenziert. Sie könnten einen Eintrag aus der Datei proposals.txt hinterlegen aus dem vorherigen Abschnitt. Zum Beispiel in einem einzelnen assoziativen Array wie folgt:

        proposer["firstname"]=$1;
        proposer["lastname"]=$2;
        proposer["email"]=$3;
        proposer["title"]=$4;

Dies macht die Textverarbeitung sehr einfach. Ein einfaches Programm, das dieses Konzept verwendet, ist die Idee eines Worthäufigkeitszählers. Sie können eine Datei parsen, Wörter in jeder Zeile aufteilen (Interpunktion ignorieren), den Zähler für jedes Wort in der Zeile erhöhen und dann die 20 wichtigsten Wörter ausgeben, die im Text vorkommen.

Zuerst in einer Datei namens wordcount.awk , setzen Sie das Feldtrennzeichen auf einen regulären Ausdruck, der Leerzeichen und Satzzeichen enthält:

BEGIN {
        # ignore 1 or more consecutive occurrences of the characters
        # in the character group below
        FS="[ .,:;()<>{}@!\"'\t]+";
}

Als nächstes iteriert die Hauptschleifenfunktion über jedes Feld, ignoriert alle leeren Felder (was passiert, wenn am Ende einer Zeile ein Satzzeichen steht) und erhöht die Wortanzahl für die Wörter in der Zeile.

{
        for (i = 1; i <= NF; i++) {
                if ($i != "") {
                        words[$i]++;
                }
        }
}

Nachdem der Text verarbeitet wurde, verwenden Sie schließlich die END-Funktion, um den Inhalt des Arrays auszugeben, und verwenden Sie dann die Fähigkeit von awk, die Ausgabe in einen Shell-Befehl zu leiten, um eine numerische Sortierung durchzuführen und die 20 am häufigsten vorkommenden Wörter auszugeben:

END {
        sort_head = "sort -k2 -nr | head -n 20";
        for (word in words) {
                printf "%s\t%d\n", word, words[word] | sort_head;
        }
        close (sort_head);
}

Das Ausführen dieses Skripts auf einem früheren Entwurf dieses Artikels erzeugte diese Ausgabe:

[[email protected]]$ awk -f wordcount.awk < awk_article.txt 
the     79
awk     41
a       39
and     33
of      32
in      27
to      26
is      25
line    23
for     23
will    22
file    21
we      16
We      15
with    12
which   12
by      12
this    11
output  11
function        11

Was kommt als nächstes?

Weitere Linux-Ressourcen

  • Spickzettel für Linux-Befehle
  • Spickzettel für fortgeschrittene Linux-Befehle
  • Kostenloser Online-Kurs:RHEL Technical Overview
  • Spickzettel für Linux-Netzwerke
  • SELinux-Spickzettel
  • Spickzettel für allgemeine Linux-Befehle
  • Was sind Linux-Container?
  • Unsere neuesten Linux-Artikel

Wenn Sie mehr über die awk-Programmierung erfahren möchten, empfehle ich dringend das Buch Sed und awk von Dale Dougherty und Arnold Robbins.

Einer der Schlüssel zum Fortschritt in der awk-Programmierung ist die Beherrschung von „erweiterten regulären Ausdrücken“. Awk bietet mehrere leistungsstarke Ergänzungen zur regulären Ausdruckssyntax von sed, mit der Sie vielleicht bereits vertraut sind.

Eine weitere großartige Ressource zum Erlernen von awk ist das GNU awk-Benutzerhandbuch. Es enthält eine vollständige Referenz für die eingebaute Funktionsbibliothek von awk sowie viele Beispiele für einfache und komplexe awk-Skripte.


Linux
  1. 13 Übungen, um Ihre Linux-Kenntnisse zu verbessern

  2. 10 Tutorials, um Ihre Kommandozeilen-Fähigkeiten zu verbessern

  3. Zwei Dateien Zeile für Zeile mit dem dreifachen Trennzeichen „|||“ zusammenführen?

  4. Sichern Sie Ihre Dateien mit rsync

  5. Wie synchronisiere ich zwei Ordner mit Befehlszeilentools?

Würzen Sie Ihren Linux-Desktop mit Cinnamon

AWK-Befehl in Linux mit Beispielen

Einfache Anleitung zur Überwachung Ihrer Systeme mit Checkmk

Testen Sie Ihre BASH-Fähigkeiten, indem Sie Kommandozeilenspiele spielen

Behandeln Sie den Zeilenumbruch mit Fold- und FMT-Befehlen im Linux-Terminal

10 Vim-Tutorials, um Ihre Editor-Fähigkeiten zu verbessern