Detaillierte Erklärung zur Verwendung von awk unter Linux

Detaillierte Erklärung zur Verwendung von awk unter Linux

Bevor wir awk lernen, sollten wir sed, grep, tr, cut und andere Befehle gelernt haben. Diese Befehle dienen alle der bequemen Text- und Datenverarbeitung unter Linux, aber wir werden feststellen, dass diese Befehle unsere Anforderungen oft nicht vollständig auf einmal erfüllen. Oft müssen wir Pipe-Symbole in Kombination mit diesen Befehlen verwenden. Heute werde ich Ihnen einen Befehl awk vorstellen, der unsere Anforderungen an die Text- und Datenverarbeitung gut erfüllen kann und es uns ermöglicht, viele Probleme mit einem Befehl zu lösen.

1. Einführung in den awk-Befehl

Awk gilt als einer der drei Musketiere der Textverarbeitung. Sein Name leitet sich von den Anfangsbuchstaben der Nachnamen seiner Gründer Alfred Aho, Peter Weinberger und Brian Kernighan ab. Tatsächlich verfügt AWK über eine eigene Sprache: die AWK-Programmiersprache, die von ihren drei Entwicklern formal als „Mustererkennungs- und -verarbeitungssprache“ definiert wurde. Sie können damit kurze Programme erstellen, die Eingabedateien lesen, Daten sortieren, Daten verarbeiten, Berechnungen mit den Eingaben durchführen und Berichte erstellen – neben unzähligen anderen Funktionen.
Daher ist awk ein leistungsstarkes Textanalysetool. Im Vergleich zur Suche mit grep und der Bearbeitung mit sed ist awk besonders leistungsstark, wenn es um die Analyse von Daten und die Generierung von Berichten geht. Einfach ausgedrückt liest awk die Datei Zeile für Zeile, schneidet jede Zeile mit Leerzeichen als Standardtrennzeichen in Scheiben und führt verschiedene Analysen und Verarbeitungen an den geschnittenen Teilen durch.

2. awk-Befehlsformat und Optionen

Grammatische Form

awk [Optionen] 'Skript' var=Wert Datei(en)
awk [Optionen] -f Skriptdatei var=Wert Datei(en)

Allgemeine Befehlsoptionen

-F fs fs gibt das Eingabetrennzeichen an, fs kann eine Zeichenfolge oder ein regulärer Ausdruck sein, beispielsweise -F:
-v var=value Weisen Sie eine benutzerdefinierte Variable zu und übergeben Sie die externe Variable an awk
-f scripfile Awk-Befehle aus einer Skriptdatei lesen
-m[fr] val setzt eine interne Grenze für den Wert von val. Die Option -mf begrenzt die maximale Anzahl der Blöcke, die val zugewiesen werden; die Option -mr begrenzt die maximale Anzahl der Datensätze. Diese beiden Funktionen sind erweiterte Funktionen der Bell Lab-Version von awk und sind im Standard-awk nicht anwendbar.

3. Das Prinzip von awk

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'

Schritt 1: Führen Sie die Anweisungen im Anweisungsblock BEGIN{ commands } aus.
Schritt 2: Lesen Sie eine Zeile aus der Datei oder der Standardeingabe (stdin) und führen Sie dann den Anweisungsblock pattern{commands} aus, der die Datei zeilenweise durchsucht und diesen Vorgang von der ersten bis zur letzten Zeile wiederholt, bis die gesamte Datei gelesen wurde.
Schritt 3: Wenn Sie bis zum Ende des Eingabestreams lesen, führen Sie den Anweisungsblock END{ commands } aus.
Der BEGIN-Anweisungsblock wird ausgeführt, bevor awk mit dem Lesen von Zeilen aus dem Eingabestream beginnt. Dies ist ein optionaler Anweisungsblock. Anweisungen wie Variableninitialisierung und Drucken von Ausgabetabellenüberschriften können normalerweise im BEGIN-Anweisungsblock geschrieben werden.

Der END-Block wird ausgeführt, nachdem awk alle Zeilen aus dem Eingabestream gelesen hat. Beispielsweise wird die Informationszusammenfassung, wie das Drucken der Analyseergebnisse aller Zeilen, im END-Block abgeschlossen. Es ist auch ein optionaler Block.

Die allgemeinen Befehle im Musterblock sind der wichtigste Teil und auch sie sind optional. Wenn der Musteranweisungsblock nicht angegeben ist, wird standardmäßig {print} ausgeführt, d. h. jede gelesene Zeile wird gedruckt und der Anweisungsblock wird für jede von awk gelesene Zeile ausgeführt.

4. Grundlegende Verwendung von awk

Es gibt drei Möglichkeiten, awk aufzurufen

1. Befehlszeilenmethode

awk [-F field-separator] 'commands' input-file(s)

Unter diesen sind die Befehle echte Awk-Befehle und [-F Feldtrennzeichen] ist optional. Eingabedatei(en) sind die zu verarbeitenden Dateien.
In awk wird jedes durch einen Feldtrenner getrennte Element in jeder Zeile einer Datei als Feld bezeichnet. Wenn Sie mit -F kein Feldtrennzeichen angeben, ist das Standardfeldtrennzeichen normalerweise ein Leerzeichen.

2. Shell-Skript-Methode

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

Ein awk-Skript besteht normalerweise aus drei Teilen: einem BEGIN-Anweisungsblock, einem allgemeinen Anweisungsblock, der Mustervergleiche verwenden kann, und einem END-Anweisungsblock. Diese drei Teile sind optional. Beide Teile müssen nicht im Skript erscheinen, das normalerweise in einfache oder doppelte Anführungszeichen eingeschlossen ist, zum Beispiel:

awk 'BEGIN{ i=0 } { i++ } END{ print i }' Dateiname
awk "BEGIN{ i=0 } { i++ } END{ print i }" Dateiname

3. Fügen Sie alle awk-Befehle in eine separate Datei ein und rufen Sie dann auf

awk -f awk-script-file Eingabedatei(en)

Die Option -f lädt das Awk-Skript in die Awk-Skriptdatei und die Eingabedatei(en) und entspricht der obigen Befehlszeilenmethode.
Schauen wir uns einige einfache Beispiele an, um die Verwendung von awk besser zu verstehen

[root@localhost ~]# awk '{print $0}' /etc/passwd 
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
Herunterfahren: x: 6: 0: Herunterfahren: / sbin: / sbin / Herunterfahren
halt:x:7:0:halt:/sbin:/sbin/halt
.................................................................................
[root@localhost ~]# echo 123|awk '{print "hallo,awk"}'
hallo, awk

[root@localhost ~]# awk '{print "hi"}' /etc/passwd
Hi
Hi
Hi
Hi
Hi
Hi
Hi
Hi
Hi
.................................................................................


Wir geben /etc/passwd als Ausgabedatei an. Wenn awk ausgeführt wird, führt es nacheinander den Druckbefehl für jede Zeile in /etc/passwd aus.

Der awk-Workflow ist wie folgt: Lesen Sie einen Datensatz, der durch ein Zeilenumbruchzeichen „\n“ getrennt ist, und teilen Sie den Datensatz dann entsprechend dem angegebenen Feldtrennzeichen in Felder auf. Füllen Sie die Felder aus. $0 steht für alle Felder, $1 für das erste Feld und $n für das n-te Feld. Das Standard-Domänentrennzeichen ist „leer“ oder „[Tabulator]-Taste“, sodass $1 den angemeldeten Benutzer darstellt, $3 die IP des angemeldeten Benutzers und so weiter. wie

Alle Benutzernamen unter /etc/passwd drucken

[root@localhost ~]# awk -F: '{print $1}' /etc/passwd
Wurzel
bin
Daemon
adm

..............................................................................
Alle Benutzernamen und UIDs unter /etc/passwd drucken

[root@localhost ~]# awk -F: '{print $1,$3}' /etc/passwd
Wurzel 0
Behälter 1
Dämon 2

..............................................................................
Ausgabe im Format Benutzername: XXX uid: XXX

[root@localhost ~]# awk -F: '{print "Benutzername: " $1 "\t\tuid: "$3}' /etc/passwd
Benutzername: root UID: 0
Benutzername: bin uid: 1
Benutzername: Daemon-UID: 2
..............................................................................


5. Integrierte awk-Variablen

Variable beschreiben
\$n Das n-te Feld des aktuellen Datensatzes, getrennt durch FS
\$0 Eingabedatensatz vervollständigen
ARGC Die Anzahl der Befehlszeilenargumente
ARGIND Die Position der aktuellen Datei in der Kommandozeile (beginnend bei 0)
ARGV Ein Array mit den Befehlszeilenargumenten
KONVERTIERUNG Numerisches Konvertierungsformat (Standardwert ist %.6g) ENVIRON Umgebungsvariable assoziatives Array
ERRNO Beschreibung des letzten Systemfehlers
FELDBREITEN Liste der Feldbreiten (durch Leerzeichen getrennt)
DATEINAME Aktueller Dateiname
FNR Zeilennummern werden für jede Datei separat gezählt
FS Feldtrennzeichen (Standard ist ein beliebiges Leerzeichen)
Groß-/Kleinschreibung ignorieren Wenn wahr, führen Sie eine Groß-/Kleinschreibung ignorierende Übereinstimmung durch.
NF Die Anzahl der Felder in einem Datensatz
NR Die Anzahl der gelesenen Datensätze, d. h. die Zeilennummer, beginnend bei 1
OFMT Ausgabeformat für Zahlen (Standard ist %.6g)
OFS Datensatztrennzeichen ausgeben (Zeilenumbruch ausgeben), Zeilenumbruch bei der Ausgabe durch das angegebene Zeichen ersetzen
ORS Trennzeichen für Ausgabedatensätze (Standard ist ein Zeilenumbruchzeichen)
RLÄNGE Die Länge der Zeichenfolge, die von der Match-Funktion abgeglichen wurde
RS Datensatztrennzeichen (Standard ist ein Zeilenumbruchzeichen)
RSTART Die erste Position in der Zeichenfolge, die von der Match-Funktion abgeglichen wurde
UNTEREP Array-Index-Trennzeichen (Standardwert ist /034)

Beispiel

[root@localhost ~]# echo -e "Zeile1 f2 f3\nZeile2 f4 f5\nZeile3 f6 f7" | awk '{print "Zeilennummer:"NR", Anzahl der Felder:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}'
Zeilennummer: 1, Anzahl der Felder: 3 $0=Zeile1 f2 f3 $1=Zeile1 $2=f2 $3=f3
Zeilennummer: 2, Anzahl der Felder: 3 $0=Zeile2 f4 f5 $1=Zeile2 $2=f4 $3=f5
Zeilennummer: 3, Anzahl der Felder: 3 $0=Zeile3 f6 f7 $1=Zeile3 $2=f6 $3=f7

Verwenden Sie print $NF, um das letzte Feld in einer Zeile zu drucken, verwenden Sie $(NF-1), um das vorletzte Feld zu drucken, und so weiter:

[root@localhost ~]# echo -e "Zeile1 f2 f3\n Zeile2 f4 f5" | awk '{print $NF}'
f3
f5
[root@localhost ~]# echo -e "Zeile1 f2 f3\n Zeile2 f4 f5" | awk '{print $(NF-1)}'
f2
f4

Statistiken zu /etc/passwd: Dateiname, Zeilennummer, Anzahl der Spalten pro Zeile und entsprechender vollständiger Zeileninhalt:

[root@localhost ~]# awk -F ':' '{print "Dateiname:" DATEINAME ",Zeilennummer:" NR ",Spalten:" NF ",Zeileninhalt:"$0}' /etc/passwd
Dateiname:/etc/passwd,Zeilennummer:1,Spalten:7,Zeileninhalt:root:x:0:0:root:/root:/bin/bash
Dateiname:/etc/passwd,Zeilennummer:2,Spalten:7,Zeileninhalt:bin:x:1:1:bin:/bin:/sbin/nologin
Dateiname:/etc/passwd,Zeilennummer:3,Spalten:7,Zeileninhalt:Daemon:x:2:2:Daemon:/sbin:/sbin/nologin

Zählen Sie die Kommandozeilenparameter ARGC, Dateizeilennummer FNR, Feldtrennzeichen FS, Anzahl der Felder in einem Datensatz NF, Anzahl der gelesenen Datensätze (Standard ist Zeilennummer) NR in der Datei /etc/passwd

[root@localhost ~]# awk -F: 'BEGIN{printf "%4s %4s %4s %4s %4s %4s\n","DATEINAME","ARGC","FNR","FS","NF","NR";printf "---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s\n",DATEINAME,ARGC,FNR,FS,NF,NR}' /etc/passwd
DATEINAME ARGC FNR FS NF NR
---------------------------------------------
/etc/passwd 2 1 : 7 1
/etc/passwd 2 2 : 7 2
/etc/passwd 2 3 : 7 3


6. Erweiterte Verwendung von awk

1.awk-Zuweisungsoperation

Zuweisungsanweisungsoperatoren: = += -= *= /= %= ^= **=

Beispiel: a+=5 ist äquivalent zu a=a+5

[root@localhost ~]# awk 'BEGIN{a=5;a+=5;print a}'
10

2. Die reguläre Betriebsausgabe von awk enthält die Root-Zeile und druckt den Benutzernamen und die UID sowie den ursprünglichen Zeileninhalt.

[root@localhost ~]# awk -F: '/root/ {print $1,$3,$0}' /etc/passwd
root 0 root:x:0:0:root:/root:/bin/bash
Operator 11 Operator:x:11:0:Operator:/root:/sbin/nologin

Wir haben zwei Zeilen gefunden. Wenn wir die Zeile finden wollen, die mit root beginnt, müssen wir sie folgendermaßen schreiben: awk -F: '/^root/' /etc/passwd

3.awk ternäre Operation

[root@localhost ~]# awk 'BEGIN{a="b";print a=="b"?"ok":"err"}'
OK
[root@localhost ~]# awk 'BEGIN{a="b";print a=="c"?"ok":"err"}'
ähm

Die ternäre Operation ist eigentlich eine Beurteilungsoperation. Wenn sie wahr ist, was dann ausgeben? Wenn es falsch ist, geben Sie Folgendes aus:

4. Zyklische Verwendung von awk

Verwendung der if-Anweisung

[root@localhost ~]# awk 'BEGIN{ test=100;if(test>90){ print "vear good";} else{print "no pass";}}'
tragen gut

Jeder Befehl endet mit ;
Die while-Schleife berechnet den Wert von 1 bis 100

[root@localhost ~]# awk 'BEGIN{test=100;num=0;while(i<=test){num+=i; i++;}print num;}'
5050
Verwendung einer For-Schleife [root@localhost ~]# awk 'BEGIN{test=0;for(i=0;i<=100;i++){test+=i;}print test;}'
5050
Verwendung einer do-Schleife [root@localhost ~]# awk 'BEGIN{test=0;i=0;do{test+=i;i++}while(i<=100)print test;}'
5050

5. Array-Anwendung von awk

Arrays sind die Seele von awk. Das Wichtigste bei der Textverarbeitung ist die Array-Verarbeitung. Da Array-Indizes (Indizes) Zahlen und Zeichenfolgen sein können, werden Arrays in awk assoziative Arrays genannt. Arrays in awk müssen weder im Voraus deklariert werden, noch muss ihre Größe angegeben werden. Array-Elemente werden je nach Kontext mit 0 oder dem leeren String initialisiert. Im Allgemeinen werden Arrays in awk verwendet, um Informationen aus Datensätzen zu sammeln, die zum Berechnen von Summen, Zählen von Wörtern, Verfolgen der Anzahl von Übereinstimmungen mit einer Vorlage usw. verwendet werden können.
Zeigen Sie das Konto in /etc/passwd an

awk -F: 'BEGIN {Anzahl=0;} {Name[Anzahl] = $1;Anzahl++;}; END{für (i = 0; i < NR; i++) drucke i, Name[i]}' /etc/passwd
0 Wurzel
1 Behälter
2 Dämon
3 Anzeige
4 LP
5 synchronisieren
..............................................................................


6. Anwendung von awk-String-Funktionen

Funktionsname Beschreibung
sub gleicht den regulären Ausdruck für die größten, ganz links stehenden Teilzeichenfolgen der Datensätze ab und ersetzt sie durch die Ersetzungszeichenfolge. Wenn keine Zielzeichenfolge angegeben ist, wird standardmäßig der gesamte Datensatz verwendet. Der Ersatz erfolgt nur beim ersten Spiel.
sub (regulärer Ausdruck, Ersetzungszeichenfolge):
sub (regulärer Ausdruck, Ersetzungszeichenfolge, Zielzeichenfolge)

Beispiele:

     awk '{ sub(/test/, "mytest"); print }' Testdatei
     awk '{ sub(/test/, "mytest"); $1}; print }' Testdatei

Das erste Beispiel stimmt mit dem gesamten Datensatz überein, und die Ersetzung erfolgt nur beim ersten Vorkommen einer Übereinstimmung. Wenn Sie die gesamte Datei abgleichen möchten, müssen Sie gsub verwenden

Das zweite Beispiel stimmt mit dem ersten Feld im gesamten Datensatz überein, und die Ersetzung erfolgt nur bei der ersten Übereinstimmung.
gsub stimmt mit dem gesamten Dokument überein
gsub (regulärer Ausdruck, Ersetzungszeichenfolge)
gsub (regulärer Ausdruck, Ersetzungszeichenfolge, Zielzeichenfolge)

Beispiele:

     awk '{ gsub(/test/, "mytest"); print }' Testdatei
     awk '{ gsub(/test/, "mytest" , $1) }; print }' Testdatei

Das erste Beispiel stimmt im gesamten Dokument mit „Test“ überein und alle Übereinstimmungen werden durch „mytest“ ersetzt.

Das zweite Beispiel gleicht das erste Feld im gesamten Dokument ab und alle Übereinstimmungen werden durch mytest ersetzt.
Index gibt die Position zurück, an der die Teilzeichenfolge zum ersten Mal übereinstimmt, wobei der Offset bei Position 1 beginnt.
Index (Zeichenfolge, Teilzeichenfolge)

Beispiele:

awk '{ print index("test", "mytest") }' testfile

Das Beispiel gibt die Position von Test in mytest zurück und das Ergebnis sollte 3 sein.
substr gibt eine Teilzeichenfolge ab Position 1 zurück. Wenn die angegebene Länge die tatsächliche Länge überschreitet, wird die gesamte Zeichenfolge zurückgegeben.
substr(Zeichenfolge, Startposition)
substr(Zeichenfolge, Startposition, Länge der Zeichenfolge)

Beispiele:

awk '{ print substr( "hello world", 7,11 ) }'

Das obige Beispiel extrahiert die Teilzeichenfolge „Welt“.
split kann einen String entsprechend dem angegebenen Trennzeichen in ein Array aufteilen. Wenn das Trennzeichen nicht angegeben ist, werden die Daten entsprechend dem aktuellen FS-Wert aufgeteilt.
split(Zeichenfolge, Array, Feldtrennzeichen)
split(Zeichenfolge, Array)

Beispiele:

awk '{ split( "20:18:00", time, ":" ); print time[2] }'

Das obige Beispiel teilt die Zeit per Doppelpunkt in das Zeitarray auf und zeigt das zweite Array-Element 18 an.
length Gibt die Anzahl der Zeichen im Datensatz zurück
Länge (Zeichenfolge)
Länge

Beispiele:

     awk '{ Drucklänge( "Test") }' 
     awk '{ Drucklänge }' Testdatei


Das erste Beispiel gibt die Länge der Testzeichenfolge zurück.

Das zweite Beispiel gibt die Anzahl der Zeichen im Datensatz in der Testdatei zurück.
match gibt den Index der Position des regulären Ausdrucks in der Zeichenfolge zurück oder 0, wenn der angegebene reguläre Ausdruck nicht gefunden wird. Die Match-Funktion setzt die integrierte Variable RSTART auf die Startposition der Teilzeichenfolge in der Zeichenfolge und RLENGTH auf die Anzahl der Zeichen bis zum Ende der Teilzeichenfolge. substr kann diese Variablen verwenden, um Zeichenfolgen abzufangen

Übereinstimmung (Zeichenfolge, regulärer Ausdruck)

Beispiele:

     awk '{start=match("das ist ein Test",/[az]+$/); print start}'
     awk '{start=match("das ist ein Test",/[az]+$/); print start, RSTART, RLENGTH }'


Das erste Beispiel druckt die Startposition der Sequenz, die mit aufeinanderfolgenden Kleinbuchstaben endet, in diesem Fall 11.

Das zweite Beispiel druckt auch die Variablen RSTART und RLENGTH, nämlich 11(start), 11(RSTART), 4(RLENGTH).
toupper und tolower können zum Konvertieren zwischen Stringgrößen verwendet werden. Diese Funktion ist nur in gawk gültig.

toupper(Zeichenfolge)
tolower(Zeichenfolge)

Beispiele:

awk '{ print toupper("test"), tolower("TEST") }'

Das könnte Sie auch interessieren:
  • Zusammenfassung der Verwendung der Split-Funktion in awk unter Linux
  • Detaillierte Erklärung des regulären Linux-Ausdrucks awk
  • Ein Shell-Befehl pro Tag. Linux-Reihe von Textinhaltsoperationen - ausführliche Erklärung des awk-Befehls
  • Detaillierte Erklärung der Verwendung von sed und awk in Linux
  • Detaillierte Erläuterung des Linux-AWK-Zeitberechnungsskripts und des Awk-Befehls
  • Einführung in die Linux-Shell awk zum Abrufen externer Variablen (Übertragung von Variablenwerten)
  • Verwendung des awk-Befehls in Linux
  • Erweiterte Linux Awk-Anwendungsbeispiele
  • Linux-AWK-Beispiel zum Trennen einer Spalte einer Datei durch Kommas

<<:  vue-table implementiert das Hinzufügen und Löschen

>>:  Tutorial zur Installation der Dekomprimierungsversion von MySQL 8.0.12

Artikel empfehlen

Tutorial zum Migrieren von Projekten von MYSQL zu MARIADB

Bereiten Sie die Datenbank (MySQL) vor. Wenn Sie ...

Verwendung des Linux-Befehls sed

1. Funktionseinführung sed (Stream EDitor) ist ei...

Wie erreicht MySQL eine Master-Slave-Synchronisierung?

Die Master-Slave-Synchronisierung, auch Master-Sl...

Implementierung eines Nginx-Load-Balancing-Clusters

(1) Experimentelle Umgebung youxi1 192.168.5.101 ...

MySQL-Einschränkungen - Super detaillierte Erklärung

Inhaltsverzeichnis MySQL-Einschränkungsoperatione...

Einführung in den CSS BEM-Benennungsstandard (empfohlen)

1 Was ist der BEM-Namensstandard Bem ist die Abkü...

Teilen Sie 20 hervorragende Beispiele für Webformular-Design

Sophie Hardach Kai von Clyde Quay 37 Ost Seifenkis...

CSS-Beispielcode zum Zeichnen eines Lutschers

Hintergrund: Machen Sie jeden Tag ein wenig Forts...