Was macht getline in awk?

Ich habe das folgende awk Skript, das die folgende Eingabedatei verwendet: input.txt und erzeugt die folgende Ausgabe. Kann sich bitte jemand die Zeit nehmen, um herauszufinden, wie dieses awk -Skript funktioniert? Ich habe ein bisschen Zeit damit verbracht und es macht nicht viel Sinn.


Eingabe:

$ cat input.txt

FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque** 

Ausgabe:

RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED 

Befehl zum Abrufen der obigen Ausgabe:

awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt 

Mein Verständnis ist, dass /FINISHED|INITIATED/ {} bedeutet, dass die Befehle in geschweiften Klammern nur in Zeilen ausgeführt werden, die entweder mit FINISHED oder INITIATED, aber als übereinstimmen Soweit ich aus der Ausgabe ersehen kann, scheint das Skript aus allen Zeilen zu analysieren. Was ist los?

Kommentare

  • Was genau verstehen Sie nicht '? Nichts? In diesem Fall: Sollen wir Ihnen das awk-Handbuch vorlesen? Andernfalls: Seien Sie genau. Die Daten werden in Variablen eingelesen und in unterschiedlicher Reihenfolge ausgegeben.
  • Ich ' Ich weiß nicht, was die Funktion getline im obigen Befehl bewirkt. Und wenn wir das Muster wie folgt angeben: /FINISHED|INITIATED/, sucht awk nach der entsprechenden Zeile und führt die Operation nur für diese bestimmte Zeile aus. Die Operation wurde jedoch für alle Zeilen ausgeführt. Wie?
  • @HaukeLaging Welche Daten werden in Variablen eingelesen und in unterschiedlicher Reihenfolge ausgegeben. Zeilenmittel?

Antwort

Die Funktion getline liest die nächste Zeile und verschiebt das Skript dorthin. Aufeinanderfolgende getline -Aufrufe werden in die nächste Zeile verschoben. Dies ist möglicherweise anhand eines Beispiels leichter zu verstehen:

$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2 

As Wie Sie oben sehen können, verarbeitet das Skript die erste Zeile, da sie mit foo übereinstimmt. Bei jedem Aufruf von getline wird die Zeile nach der aktuellen gelesen, sodass die nachfolgenden print -Aufrufe die nächsten Zeilen drucken.

Antwort

Wenn Sie nicht wissen, was eine awk -Funktion tut, ist die übliche Strategie Um einen Blick auf die Manpage zu werfen:

getline

Setzen Sie $ 0 aus dem nächsten Eingabedatensatz; setzen Sie NF, NR, FNR, RT

Der Befehlsblock wird tatsächlich nur zweimal ausgeführt. Die anderen Zeilen werden über getline aus dem Block.

Dies könnte umgeschrieben werden in:

/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ... 

Kommentare

  • Was passiert, wenn der nächste Datensatz leer ist?
  • @AvinashRaj Weder Ihr Code noch meine Alternative betrachten den Inhalt der Zeilen (mit Ausnahme von /FINISHED|INITIATED/ ). Die Zeilen werden nur heruntergezählt. Die Daten müssen genau angeordnet sein (von einem awk parsi ng Perspektive) in der Weise, wie Sie es sonst gezeigt haben, wird der Code brechen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.