selektives Löschen von Linien zwischen zwei Mustern

selektives Löschen von Linien zwischen zwei Mustern

Ich habe eine Datei, die folgenden Inhalt enthält,

Hello world Unix!!
Its bright world
Current time is HH:mm:ss
Next action plan is item #3
End of task.
Thank you.


Hello world Linux!!
All actions completed.
End of Activity.
Thanks.

Ich möchte selektiv alle Zeilen löschen, die das Schlüsselwort „Welt“ enthalten, und auch alle nachfolgenden Zeilen, bis eine Zeile mit einem bestimmten Satz von Schlüsselwörtern (Beispiel: „Aktivität“ oder „Aufgabe“) gefunden wird.

Gewünschte Ausgabe:

End of task.
Thank you.
End of Activity.
Thanks. 

Antwort1

Versuchen:

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f' File
End of task.
Thank you.


End of Activity.
Thanks.

Wie es funktioniert:

  1. -v f=1

    Erstellen Sie eine Awk-Variable fund setzen Sie sie auf 1.

  2. /world/{f=0}

    Wenn die aktuelle Zeile enthält world, setzen Sie die Variable fauf Null.

  3. /Activity|task/{f=1}

    Wenn die Zeile entweder Activityoder enthält task, dann setzen Sie fauf 1.

    Beachten Sie, dass worldoben und Activityoder taskhier als reguläre Ausdrücke behandelt werden. Außerdem wird zwischen Groß- und Kleinschreibung unterschieden.

  4. f

    Wenn fder Wert ungleich Null ist, drucken Sie die Zeile.

So löschen Sie auch Leerzeilen

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f && /./' File
End of task.
Thank you.
End of Activity.
Thanks.

f && /./weist awk an, die Zeile nur zu drucken, wenn fsie ungleich Null ist.Unddie Zeile enthält mindestens ein Zeichen (beliebiger Art).

Antwort2

Nicht so schön wie die awk-Lösung, aber da der OP die Frage mit markiert hatsedalso, hier ist es:

#with blank lines
sed '/world/,/task\|Activity/{//!d};/world/d' file

#without blank lines
sed '/world/,/task\|Activity/{//!d};/world\|^$/d' file

Beachten Sie die Verwendung von //, was den zuvor verwendeten regulären Ausdruck bedeutet :)

verwandte Informationen