Heim >php教程 >PHP开发 >Detaillierte Erklärung des awk-Befehls

Detaillierte Erklärung des awk-Befehls

高洛峰
高洛峰Original
2016-12-15 11:06:381473Durchsuche

1. Vorwort

Awk hat 3 verschiedene Versionen: awk, nawk und gawk. Wenn nicht anders angegeben, bezieht es sich im Allgemeinen auf gawk. Die grundlegendste Funktion der awk-Sprache besteht darin, Informationen basierend auf bestimmten Regeln aus Dateien oder Zeichenfolgen zu zerlegen und zu extrahieren, und sie kann auch Daten basierend auf bestimmten Regeln ausgeben. Vollständige AWK-Skripte werden typischerweise zum Formatieren von Informationen in Textdateien verwendet.

2. Grundlegende Syntax

awk [opion] 'awk_script' input_file1 [input_file2 ...]

Die allgemeinen Optionen von awk sind:

① -F fs: Verwenden Sie fs als Feldtrennzeichen für Eingabedatensätze. Wenn diese Option weggelassen wird, verwendet awk den Wert der Umgebungsvariablen IFS

② -f Dateiname: Liest awk_script

aus Datei Dateiname ③ -v var=Wert: Variablen für awk_script festlegen

Awk hat drei Ausführungsmodi:

Der erste besteht darin, den awk-Skriptbefehl direkt in den Befehl einzufügen.

Zweitens fügen Sie alle Skriptbefehle von awk in eine Skriptdatei ein und verwenden Sie dann die Option -f, um die auszuführende Skriptbefehlsdatei anzugeben.

Die dritte Methode besteht darin, awk_script in die Skriptdatei einzufügen und #!/bin/awk -f als erste Zeile zu verwenden, dem Skript die Ausführberechtigung zu erteilen und es dann aufzurufen, indem Sie den Skriptnamen in die Shell eingeben .

3. Awk-Skript

Awk-Skript kann aus einem oder mehreren awk_cmd bestehen, nachdem ein awk_cmd abgeschlossen ist, sollte eine neue Zeile zur Trennung begonnen werden.

awk_cmd besteht aus zwei Teilen: awk_pattern { Aktionen }.

Darüber hinaus kann awk_script bei der direkten Verwendung von awk_script im awk-Befehl auch in mehreren Zeilen geschrieben werden, Sie müssen jedoch darauf achten, dass das gesamte awk_script in einfache Anführungszeichen gesetzt wird.

Die allgemeine Form des awk-Befehls:

awk ' BEGIN { Aktionen }

awk_pattern1 { Aktionen }

...... ..

awk_patternN { Actions }

END { Actions }

' Eingabedatei

wobei BEGIN { Actions } und END { Actions } optional sind.

Sie können AWKs eigene integrierte Variablen im awk-Skript wie folgt verwenden:

ARGC-Anzahl der Befehlszeilenargumente

ARGV-Befehlszeilenargumentarray

FILENAME aktueller Eingabedateiname

FNR-Datensatznummer in der aktuellen Datei

FS-Eingabefeldtrennzeichen, der Standardwert ist ein Leerzeichen

RS-Eingabedatensatztrennzeichen

NF Anzahl der Felder im aktuellen Datensatz

NR Anzahl der bisherigen Datensätze

OFS Ausgabefeldtrennzeichen

ORS Ausgabedatensatztrennzeichen

awk-Skript Laufender Prozess:

① Wenn der BEGIN-Block vorhanden ist, führt awk die von ihm angegebenen Aktionen aus.

② awk liest eine Zeile aus der Eingabedatei, die als Eingabedatensatz bezeichnet wird. (Wenn die Eingabedatei weggelassen wird, wird sie aus der Standardeingabe gelesen)

③ awk teilt den gelesenen Datensatz in Felder auf, fügt das erste Feld in die Variable $1, das zweite Feld in $2 usw. ein An. $0 repräsentiert den gesamten Datensatz. Feldtrennzeichen werden mithilfe der Shell-Umgebungsvariablen IFS oder durch Parameter angegeben.

④ Vergleichen Sie den aktuellen Eingabedatensatz mit dem awk_pattern in jedem awk_cmd, um zu sehen, ob er übereinstimmt. Wenn er übereinstimmt, führen Sie die entsprechenden Aktionen aus. Wenn keine Übereinstimmung vorliegt, werden die entsprechenden Aktionen übersprungen, bis alle awk_cmds verglichen wurden.

⑤ Wenn ein Eingabedatensatz alle awk_cmd vergleicht, liest awk die nächste Zeile der Eingabe und wiederholt die Schritte ③ und ④. Dieser Vorgang wird fortgesetzt, bis awk das Ende der Datei liest.

⑥ Nachdem awk alle Eingabezeilen gelesen hat und END vorhanden ist, werden die entsprechenden Aktionen ausgeführt.

1) input_file kann eine Dateiliste mit mehr als einer Datei sein, und awk verarbeitet jede Datei in der Liste der Reihe nach.

2) Ein awk_pattern von awk_cmd kann weggelassen werden, wenn es weggelassen wird, werden die entsprechenden Aktionen ohne Abgleich und Vergleich der Eingabedatensätze ausgeführt. Eine awk_cmd-Aktion kann auch weggelassen werden. Wenn sie weggelassen wird, besteht die Standardaktion darin, den aktuellen Eingabedatensatz zu drucken, also {print $0}. Awk_pattern und Aktionen in einem awk_cmd können nicht gleichzeitig weggelassen werden.

3) Der BEGIN-Block und der END-Block befinden sich am Anfang bzw. am Ende von awk_script. In awk_script sind nur END-Blöcke oder nur BEGIN-Blöcke erlaubt. Wenn in awk_script nur BEGIN { actions } vorhanden ist, liest awk die Eingabedatei nicht.

4) awk liest die Daten der Eingabedatei in den Speicher und erstellt dann eine Kopie der Eingabedaten im Speicher. awk ändert den Inhalt der Eingabedatei nicht.

5) awk gibt immer in die Standardausgabe aus. Wenn Sie möchten, dass awk in eine Datei ausgibt, können Sie die Umleitung verwenden.

3.1.awk_pattern

Der Musterteil awk_pattern bestimmt, wann der Aktionsteil Aktionen auslöst und löst Aktionen aus.

awk_pattern kann von den folgenden Typen sein:

1) Regulärer Ausdruck wird als awk_pattern verwendet: /regexp/

Beachten Sie, dass der reguläre Ausdruck regexp mit / umschlossen sein muss

Zeichen, die häufig in regulären Ausdrucksabgleichsoperationen in awk verwendet werden:

^ $ [] | () * //: Gemeinsame reguläre Ausdrucks-Metazeichen

+: Entspricht dem einzelnen Zeichen davor Mehr als einmal. Es ist das eigene Metazeichen von awk. Es ist nicht für grep geeignet oder sed usw.

Weitere Informationen zu regulären Ausdrücken finden Sie unter „Reguläre Ausdrücke“

Beispiel:

awk '/ *$0. [0-9].*/' input_file

Der Zeileninhalt beträgt beispielsweise 0,99 $. Die Helllo-Zeile kann mit dem obigen regulären Ausdruck übereinstimmen

2) Boolescher Ausdruck Der Ausdruck wird als awk_pattern verwendet Sobald der Ausdruck erstellt ist, wird die Ausführung der entsprechenden Aktionen ausgelöst.

① Sie können Variablen (z. B. Feldvariablen $1, $2 usw.) und /regexp/

② Operatoren in booleschen Ausdrücken verwenden:

Relationaler Operator: < > <= >= == !=

Übereinstimmungsoperator: Wert ~ /regexp/, wenn der Wert mit /regexp/ übereinstimmt, wird der wahre

Wert zurückgegeben !~ /regexp/ Wenn der Wert nicht mit /regexp/ übereinstimmt, geben Sie true zurück

Beispiel: awk '$2 > 10 {print "ok"}' input_file

awk '$3 ~ /^ d/ {print "ok"}' input_file

③ && (und) und || (oder) können zwei /regexp/ oder boolesche Ausdrücke verbinden, um einen gemischten Ausdruck zu bilden. !(not) kann in booleschen Ausdrücken oder vor /regexp/ verwendet werden.

Beispiel: awk '($1 < 10 ) && ($2 > 10) {print $0 "ok"}' input_file

awk '/^d/ || /x$/. {print $0 "ok"}' input_file

④ Andere Ausdrücke werden als awk_script verwendet, z. B. Zuweisungsausdrücke usw.

Beispiel:

awk '(tot+=$6 ); END{print "total point :" tot }' input_file // Semikolon kann nicht weggelassen werden

awk 'tot+=$6 {print $0} END{print "total point :" tot }' input_file // Das Gleiche wie oben Effektiv

Bei Verwendung eines Zuweisungsausdrucks bedeutet dies, dass die zugewiesene Variable, wenn sie nicht 0 ist, übereinstimmt, andernfalls nicht übereinstimmt, wenn es sich um eine Zeichenfolge handelt Es ist nicht leer, es wird übereinstimmen, andernfalls wird es nicht übereinstimmen.


awk integrierte String-Funktion:

gsub(r, s) Ersetzen Sie r durchgehend durch s $0

awk 'gsub ( /name/, "xingming") {print $0}' temp

gsub(r, s, t) Ersetzen Sie r

index(s, t) durch s im gesamten t. Geben Sie The zurück erste Position der Zeichenfolge t in s

awk 'BEGIN {print index("Sunny", "ny")}' temp Gibt 4

length(s) zurück. Gibt die Länge von s

match(s, r) Testen Sie, ob s eine Zeichenfolge enthält, die mit r übereinstimmt

awk '$1=="J.Lulu" {print match($1, "u")}' temp Return 4

split(s, a, fs) Teile s in die Sequenz a

awk 'BEGIN {print split("12#345#6789", myarray, "#") on fs "'

gibt 3 zurück, während myarray[1]="12", myarray[2]="345", myarray[3]="6789"

sprint(fmt, exp) Exp zurückgibt

sub(r, s) nach der Formatierung durch fmt Ersetzen Sie r durch s aus der ganz linken längsten Teilzeichenfolge in $0 (ersetzen Sie nur die erste passende Zeichenfolge)

substr(s, p) Gibt zurück der Suffixteil, der bei p in der Zeichenfolge s beginnt

substr(s, p, n) Gibt den Suffixteil zurück, der bei p beginnt und die Länge n in der Zeichenfolge s hat

awk-String-Verkettungsoperation

[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a""b);print c} '

ab

2.7. Verwendung der printf-Funktion:

Zeichenkonvertierung: echo "65" |awk '{printf "%cn",$0}' Ausgabe A

awk 'BEGIN {printf "% fn",999}' Ausgabe 999.000000

Formatierte Ausgabe: awk '{printf "%-15s %sn",$1,$3}' temp wird das erste sein. Alle Felder in einem Feld werden linksbündig ausgerichtet und angezeigt

2.8. Andere awk-Verwendungen:

Übergabe von Werten an eine Zeile von awk-Befehlen:

awk '{if ($5

who | awk ' {if ($1==user) print $1 " are in " $2 ' user=$LOGNAME Verwenden Sie die Umgebungsvariable

awk-Skriptbefehl: Verwenden Sie !/bin/awk am Anfang von

- f , ohne diesen Satz wird das eigenständige Skript nicht ausgeführt, Beispiel:

!/bin/awk -f

# alle Kommentarzeilen müssen mit einem Hash '#' beginnen

# Name: student_tot.awk

# anzurufen: student_tot.awk grade.txt

# druckt Gesamt- und Durchschnitt der Club-Studentenpunkte

# druckt a Kopfzeile zuerst

BEGIN

{

Drucken Sie „Student Date Member No. Note Age Points Max“

Drucken Sie „Name beigetreten, gewonnene Punkte verfügbar“

drucken"========================================== ============="

}

# addieren wir die erzielten Punkte

(tot+=$6);

# Verarbeitung abgeschlossen Jetzt drucken wir die Gesamt- und Durchschnittspunktzahl aus

ENDE

{

print „Gesamtpunktzahl der Clubstudenten:“ tot

print „Durchschnittliche Club-Studentenpunkte:“ ges./N

}


2.9 awk-Array:

Grundlegende Schleifenstruktur von awk

Für (Element im Array) print array[element]

awk 'BEGIN {record="123#456#789";split(record, myarray, "#")}

END { for (i in myarray) {print myarray[i]} }

3.0 Benutzerdefinierte Anweisungen in awk

1. Bedingte Beurteilungsanweisung (if)


if (expression) #if ( Variable in Array )

Anweisung 1

else

Anweisung 2

„Anweisung 1" im Format können mehrere Anweisungen sein. Wenn Sie die Beurteilung von Unix awk und Ihr eigenes Lesen erleichtern möchten, sollten Sie mehrere Anweisungen besser mit {} einschließen. Die Unix-awk-Zweigstruktur ermöglicht eine Verschachtelung, ihr Format ist:


if(expression)


{Anweisung 1}


else if (expression)

{Anweisung 2}

else

{Anweisung 3}

[chengmo@localhost nginx]# awk 'BEGIN {

test=100;

if(test>90)

{

print „sehr gut“;

}

else if(test>60)

{

print "good";

}

else

{

print „no pass“;

}

}'


sehr gut



Jede Befehlsanweisung kann mit einem „;“ beendet werden.



2. Schleifenanweisungen (while, for, do)


1.while-Anweisung


Format:


while (Ausdruck)


{Anweisung}

Beispiel:


[chengmo@localhost nginx]# awk 'BEGIN{

test=100;

total=0;

while(i<=test)

{

total+=i;

i++;

}

print total;

}'

5050

2. for-Schleife


Die for-Schleife hat zwei Formate:


Format 1:


für (Variable im Array)


{Anweisung}


Beispiel:


[chengmo@localhost nginx]# awk 'BEGIN{

for(k in ENVIRON)

{

print k"=" ENVIRON [k];

}

}'


AWKPATH=.:/usr/share/awk

OLDPWD=/home/web97

SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass

SELINUX_LEVEL_REQUESTED=

SELINUX_ROLE_REQUESTED=

LANG = zh_CN.GB2312


. . . . . .


Erklärung: ENVIRON ist eine awk-Konstante und ein subtypisches Array.


Format 2:


für (Variable; Bedingung; Ausdruck)


{Anweisung}


Beispiel:


[chengmo@localhost nginx]# awk ' BEGIN{

total=0;

for(i=0;i<=100;i++)

{

total+=i;

}

Summe drucken;

}'


5050

3.do-Schleife


Format:


do


{statement} while (Bedingung)


Beispiel:


[chengmo@localhost nginx]# awk 'BEGIN{

total=0;

i=0;

tun

{

total+=i;

i++;

}while(i<=100)

print total;

}'

5050


Das Obige ist die awk-Flusskontrollanweisung. Anhand der Syntax können Sie erkennen, dass sie mit der C-Sprache identisch ist. Mit diesen Anweisungen können viele Shell-Programme tatsächlich an awk übergeben werden, und die Leistung ist sehr schnell.


break Wenn die break-Anweisung in einer while- oder for-Anweisung verwendet wird, wird die Programmschleife beendet.

continue Wenn die continue-Anweisung in einer while- oder for-Anweisung verwendet wird, wird die Programmschleife mit der nächsten Iteration fortgefahren.

next bewirkt, dass die nächste Eingabezeile gelesen wird, und kehrt zum Anfang des Skripts zurück. Dadurch wird vermieden, dass zusätzliche Operationen in der aktuellen Eingabezeile ausgeführt werden. Die

exit-Anweisung bewirkt, dass die Haupteingabeschleife beendet wird und die Steuerung an END übergeben wird, sofern END vorhanden ist. Wenn keine END-Regel definiert ist oder in END eine Exit-Anweisung angewendet wird, wird die Ausführung des Skripts beendet.


NR und FNR:

ZITAT:

A. Die Ausführungssequenz von awk für mehrere Eingabedateien besteht darin, dass der Code zuerst auf die erste Datei angewendet wird (Zeile für Zeile gelesen) und dann der wiederholte Code auf die zweite Datei und dann auf die dritte Datei angewendet wird.

B. Die Ausführungsreihenfolge von Awk für mehrere Eingabedateien führt zu einem Problem mit der Zeilennummer. Wie berechnet man die erste Zeile der zweiten Datei, wenn die erste Datei ausgeführt und die zweite Datei das nächste Mal gelesen wird? Wenn es wieder als 1 zählt, wären es dann nicht zwei Einsen? (Weil die erste Datei auch die erste Zeile hat). Das ist das Problem bei NR und FNR.

NR: Globale Zeilennummer (die erste Zeile der zweiten Datei gefolgt von der letzten Zeilennummer der ersten Datei wird fortlaufend gezählt)

FNR: Die Anzahl der Zeilen der aktuellen Datei selbst (unabhängig von den vorherigen) Geben Sie die Anzahl der Zeilen und die Gesamtzahl der Datei selbst ein)

Beispiel: Es gibt 40 Zeilen in data1.txt und 50 Zeilen in data2.txt, dann awk '{} ' data1.txt data2.txt

Die Werte von NR sind: 1, 2...40, 41, 42...90

Die Werte von FNR sind: 1, 2...40, 1, 2...50

getline-Funktionsbeschreibung:

awks getline-Anweisung wird verwendet, um einfach einen Datensatz zu lesen. Getline ist besonders nützlich, wenn der Benutzer über einen Datensatz verfügt, der zwei physischen Datensätzen ähnelt. Es vervollständigt die Trennung allgemeiner Felder (Feldvariablen $0 FNR NF NR festlegen). Gibt 1 bei Erfolg zurück, 0 bei Fehler (Ende der Datei erreicht).

ZITAT:

A. Im Allgemeinen sollte die Verwendung von getline wie folgt verstanden werden:

Wenn links und rechts keine Umleitungszeichen vorhanden sind, wirkt getline auf die aktuelle Datei und liest die erste Zeile der aktuellen Datei und geben Sie es an die folgende Variable

weiter

        var oder $0 (keine Variable); es ist zu beachten, dass das Rückgabeergebnis von getline getting

            interlaced ist, da awk eine Zeile gelesen hat, bevor getline verarbeitet wurde.

Wenn eine Umleitungsrune vorhanden ist, wird sie von

auf die direktionale Eingabedatei eingelesen AWK, einfach getline einlesen, dann gibt getline die erste Zeile der Datei zurück, nicht jede zweite Zeile.

B. Die Verwendung von getline kann grob in drei Hauptkategorien unterteilt werden (jede Hauptkategorie ist in zwei Unterkategorien unterteilt), d. h. es gibt insgesamt 6 Verwendungen. Der Code lautet wie folgt:

QUOTE:

nawk 'BEGIN{"cat data.txt"|getline d; data2.txt

nawk 'BEGIN {"cat data.txt"|getline; print $0}' data2.txt

nawk 'BEGIN{getline d < "data.txt"}' data2.txt

nawk 'BEGIN {getline < „data.txt“; print $0}' data2.txt

Die oben genannten vier Codezeilen implementieren alle „nur die erste Zeile der data.txt-Datei drucken“ (beim Drucken). alle Zeilen, verwenden Sie eine Schleife)

zB >


Zitat:

nawk '{getline d; print d“#“$3}' data.txt

awk liest zuerst die erste Zeile , und verarbeitet dann die getline-Funktion. Weisen Sie dann die nächste Zeile der Variablen d zu und drucken Sie dann zuerst d. Da nach d ein Zeilenumbruchzeichen steht, überschreibt das folgende # d und das folgende $ 3 überschreibt auch d.

Zitat:

nawk '{getline; print $0“#“$3}' data.txt

awk liest zuerst die erste Zeile und verarbeitet dann die getline-Funktion und then Die nächste Zeile wird $0 zugewiesen. Jetzt ist $0 der Inhalt der nächsten Zeile. Das folgende # und $3 (von $0 übernommen) überschreiben den Inhalt von $0.

In awk ist es manchmal erforderlich, Systemtools aufzurufen, um Aufgaben auszuführen, für die awk nicht geeignet ist. Der von awk bereitgestellte Systembefehl kann zum Ausführen verwendet werden, die Ausgabeergebnisse externer Tools können jedoch nicht empfangen werden. Glücklicherweise können Sie getline verwenden, um diese Anforderung zu erfüllen. Zum Beispiel

test.awk:

{

datecommand="/bin/date -j -f "%d/%b/%Y:%H:% M :%S" " $olddatestr " "+%Y%m%d %H%M%S"";

getline newdatestr

close(datecommand);

}

Externe Befehle erfordern, dass awk einen Dateideskriptor belegt, und die maximale Anzahl von Dateien, die awk öffnen kann, hat eine Obergrenze und ist nicht groß (z. B. 16), also endlich einen Abschluss machen Es ist eine gute Angewohnheit. Das Definieren der Befehlszeichenfolge als Variable erleichtert auch das Schließen.



Für detailliertere Erläuterungen zu awk-Befehlen und verwandten Artikeln zahlen Sie bitte Achtung auf die chinesische PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn