Ist die Verwendung von getline im Awk-Befehl sicher?

Ist die Verwendung von getline im Awk-Befehl sicher?

Ich habe seltsame Kommentare zum Posten einer awkAntwort auf SO erhalten, die diese Funktion verwendet getline. Hierist der Link zu dieser Antwort.

Nachdem ich meine Antwort gepostet hatte, kommentierte ein Benutzer Folgendes ( ich kritisiere ihn nicht ) .

Keine gute Lösung, da die Zeilen unabhängig vom Inhalt verbunden werden und bei Bedarf keine weiteren Zeilen verarbeitet werden. Außerdem sollten Sie getline nicht verwenden.

getlineEs besagt, dass wir die Funktion in vermeiden sollten awk. Meine Fragen sind also:

  • getlineIst es sicher , Funktionen in Awk zu verwenden ?
  • Unter welchen Umständen sollten wir es verwenden, und getlineunter welchen nicht?
  • Wenn diese Funktion unerwartete Ergebnisse produziert, warum reichen wir dann keinen Fehlerbericht ein?

Antwort1

Die meisten Menschen streiten sich getlineüberKodierungsstilBoden.

Es ist für die normale Verarbeitung fremd, awkwenn der Code jeweils nur einen Datensatz verarbeitet.

getlinegetline var < "file"(wenn nicht als oder verwendet "cmd" | getline) zieht den nächsten Datensatz (möglicherweise aus der nächsten Datei) in die Mitte der Codeanweisung. Man kann leicht den Überblick darüber verlieren, dass NR, FNR erhöht werden und sich FILENAME ändern kann.

Eine weitere Sache, die Sie bei der Verwendung nicht vergessen dürfen, ist, den Rückgabewert zu überprüfen, da dieser bei EOF 0 und im Fehlerfall <0 zurückgibt.

Es ist also nicht getlineoder if/while (getline) ..., sondern:

if/while ((getline) > 0) { .... }

Oder:

if/while ((getline < "file") > 0) {...}

Die meisten Verwendungen getlinekönnen durch die Verwendung eines zustandsmaschinenähnlichen Ansatzes umgekehrt werden.

Anstatt:

/pattern/ {getline; print}

Was wahrscheinlich falsch ist und geschrieben werden sollte:

/pattern/ && (getline) > 0 {print}

Du würdest:

found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}

Beachten Sie auch, wie sich die beiden unterscheiden, wennMusterwird in zwei aufeinanderfolgenden Zeilen abgeglichen.

Solange Sie sich dessen bewusst sind, getlineist alles in Ordnung. Wenn Sie mehrere Dateien gleichzeitig verarbeiten möchten, benötigen Sie getline, aber denken Sie daran, den Rückgabewert zu überprüfen:

while ((getline a < "a") > 0 && (getline b < "b") > 0) {
  ....

verwandte Informationen