2012-04-19 20 views
10

getline in der nächsten Zeile liest und erhöht die NR Zähler um 1 Nach der Verwendung von getline, awk Lebensläufe mit der nächsten Zeile zu arbeiten. Dies ist in den meisten Fällen das gewünschte Verhalten.Peek bei der nächsten Zeile, aber nicht verbraucht es

In meiner speziellen Situation brauche ich nur die nächste Zeile zu sehen und je nach Inhalt lese ich die nächste Zeile oder ich muss eine Zeile zurückverfolgen.

Wie kann ich eine Zeile in awk zurückverfolgen? Ich habe versucht, die NR Zähler manuell auf setzen, aber das funktioniert nicht. Oder gibt es eine Methode, die nur auf die nächste Zeile schaut, ohne NR zu ändern?

Ich brauche ein Lookahead von einer Zeile. Einfach die Zeile in einer Variablen zu speichern und später darauf zu verweisen, funktioniert in diesem Fall nicht. Ich versuche, ein literarisches Programmiertool in awk zu implementieren, wo eine Hauptdatei viele Unterdateien enthalten kann. Eine solche Subdatei beginnt mit einer Zeile wie "% file:file1". Das Ende einer solchen Datei ist erreicht, wenn eine Zeile mit einer tieferen Einrückung oder eine andere Zeile mit einer Zeile wie "% file:file2" erreicht wird.

Die Regel für alle Zeilen passend /% file:/ wird nicht verwendet, wenn ich diese Zeile bereits mit getline gelesen habe. Deshalb würde ich gerne NR auf die vorherige Zeile zurücksetzen, dann würde awk die Zeile wieder lesen, die /% file:/ entspricht, und die entsprechende Regel würde ausgeführt werden.

+1

Ich entwickelte eine Text-Munge-Sprache namens TXR, die Mustererkennung mit implizitem Backtracking sowohl in zeilenorientierten ("vertikalen") als auch zeichenorientierten ("horizontalen") Anpassungsmodi bietet. Die Lookahead-Tiefe ist eine beliebige Anzahl von Zeichen oder Zeilen. TXR ist nahezu ideal für die Verarbeitung einer Programmiersprache. Es ist schwer, ein direkt relevantes Beispiel zu geben; Können Sie eine vollständige Spezifikation der Notation schreiben? – Kaz

Antwort

1

Dies ist ein bisschen wie ein Hack und ist ziemlich teuer, aber für kleine Dateien, machen Ihnen einen Look-Ahead geben:

cmd="sed -n " NR + 1 "p " FILENAME; cmd | getline nextline 

dass den aktuellen Wert von NR nehmen und verwenden sed Linie NR zu extrahieren + 1 aus der Eingabedatei. Das ist teuer, weil sed jedes Mal, wenn Sie einen Lookahead machen, die gesamte Datei durchliest (Sie können das etwas lindern, indem Sie sd einen Befehl 'q' hinzufügen). Die Variable nextline wird auf die nächste Zeile der Datei gesetzt und in der letzten Zeile leer gelassen.

10

Dies kann nähern, was Sie suchen und sollte nicht so teuer wie die sed Lösung sein, da AWK einen Zeiger in der Datei verwaltet, die getline öffnet.

awk 'FNR == 1 { 
     getline nextline < FILENAME 
    } 
    { 
     getline nextline < FILENAME; 
     print "currentline is:", $0; 
     print "nextline is: ", nextline 
    }' input file 

Der erste Block liest die erste Zeile und verschwendet sie.

In dieser Form getline stellt nicht alle Variablen wie NR, FNR, NF oder $0. Es legt nur die Variable fest, die Sie angeben (nextline in diesem Fall).

Weitere Informationen finden Sie unter this.

+0

Schade, das ist scheinbar GNU awk spezifisch. – 0xC0000022L

+0

@ 0xC0000022L: Es funktioniert für mich unter 'Mawk'. –

Verwandte Themen