Wie entfernt `awk 'NF {p=1} p'` Leerzeilen vom Anfang und Ende einer Datei?

Wie entfernt `awk 'NF {p=1} p'` Leerzeilen vom Anfang und Ende einer Datei?

Auf der Suche nach einer Möglichkeit, Leerzeilen am Anfang und Ende taceiner Datei zu entfernen (mithilfe von ), bin ich über diese gestolpert:

awk 'NF {p=1} p'

Wie/warum funktioniert das?

Ich verstehe NFdas nur true, wenn Felder vorhanden sind (wenn die Zeile keine leere Zeile ist).

Antwort1

Dadurch werden leere Zeilen am Anfang entfernt.aber nicht vom Endeeiner Datei.[Hinweis: Diese Antwort wurde vor demBearbeiten der Fragedas erwähnte tac]

Es funktioniert wie folgt:

  • NFist die Anzahl der in der aktuellen Zeile gefundenen Felder. Wenn sie Null ist, bedeutet das, dass die Zeile entweder leer ist oderleer, d. h. es enthält höchstens Leerzeichen (vorausgesetzt, der Feldtrenner wird auf seinem Standardwert belassen, bei dem jede Anzahl aufeinanderfolgender Leerzeichen als Trennzeichen betrachtet wird).
  • Die aktuelle Zeile wird gedruckt, wenn eine beliebige Bedingung außerhalb von Regelblöcken () (und die nicht mit diesen verknüpft ist) { ... }als ausgewertet wird true. Das Flag pist zunächst nicht initialisiert und wird als ausgewertet false, daher wird a priori nichts gedruckt.
  • Sobald eine nicht leere Zeile gefunden wird ( NFdie ungleich Null ist und als ausgewertet wird true), {p=1}wird der Regelblock aufgerufen und das Flag pauf gesetzt 1. Danach wird der Bereich paußerhalb des Regelblocks als ausgewertet trueund alle nachfolgenden Zeilen (einschließlich der aktuellen, ersten nicht leeren Zeile) werden gedruckt.

Beachtendass, da das Flag pnie zurückgesetzt wird, alle Leerzeilen nach der ersten nicht leeren Zeile ohne Filterung gedruckt werden. Wenn Sie auch am Ende Leerzeilen entfernen möchten, ist ein zweistufiger Ansatz erforderlich:

awk 'FNR==NR{if (NF) {if (!first) first=FNR; last=FNR} next}
     FNR>=first && FNR<=last' input.txt input.txt

Dadurch wird die Datei zweimal verarbeitet (daher wird sie zweimal als Operand angegeben).

  • Im ersten Durchgang, bei dem FNRder Zeilenzähler pro Datei gleich NRdem globalen Zeilenzähler ist, identifizieren wir die erste und die letzte nicht leere Zeile.
  • Im zweiten Durchgang ( FNRist jetzt kleiner als NR) drucken wir nur die Zeilen zwischen (und einschließlich) der so identifizierten ersten und letzten nicht leeren Zeile.

Beachten

Wie in derAntwort von Stéphane Chazelasfunktioniert der Zwei-Durchgang-Ansatz nur mit regulären Dateien. Wenn Ihre Eingabe anderer Natur ist, finden Sie eine Lösung in der dort vorgeschlagenen Methode.

Antwort2

Verwenden Sie diese Technik, um leere Zeilen sowohl aus dem Kopf als auch aus dem Ende der Datei zu entfernen:

awk 'NF {p=1} p' file | # remove blank lines at the file head
  tac |                 # reverse the lines
  awk 'NF {p=1} p' |    # remove blanks from the "new head"
  tac |                 # re-reverse the file
  sponge file           # from the `moreutils` package, to overwrite the file

Antwort3

Was Dein Code macht und warum er nur leere Zeilen am Anfang der Eingabe löscht, wurde bereits erklärt in@AdminBees Antwortzum Beispiel, aber der Vollständigkeit halber schlage ich hier eine alternative Methode vor, um sowohl führende als auch nachfolgende Leerzeilen zu entfernen, ohne die Datei zweimal durchgehen zu müssen (was nur bei normalen Dateien und nicht bei beliebigen Eingaben funktionieren würde).

awk '
       NF {print saved $0; saved = ""; started = 1; next}
  started {saved = saved $0 ORS}' < file

Dabei verzögern wir das Drucken von Leerzeilen bis zur nächsten nicht leeren Zeile, die wir danach sehen (vorausgesetzt, wir haben zuvor bereits mindestens eine nicht leere Zeile gesehen).

Antwort4

Falls es Ihnen nichts ausmacht, alle Leerzeichen oder Tabulatoren in den Leerzeilen zu überschreiben, die Sie behalten möchten, werden hiermit die Leerzeilen am Anfang und Ende entfernt:

awk 'NF{for(;c;--c)print "";print;x=1;next} x{++c}'

Es zählt, wie viele Leerzeilen zwischen nicht leeren Zeilen vorkommen, und druckt entsprechend viele Leerzeilen vor jeder nicht leeren Zeile.

verwandte Informationen