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:
-v f=1
Erstellen Sie eine Awk-Variable
f
und setzen Sie sie auf1
./world/{f=0}
Wenn die aktuelle Zeile enthält
world
, setzen Sie die Variablef
auf Null./Activity|task/{f=1}
Wenn die Zeile entweder
Activity
oder enthälttask
, dann setzen Sief
auf1
.Beachten Sie, dass
world
oben undActivity
odertask
hier als reguläre Ausdrücke behandelt werden. Außerdem wird zwischen Groß- und Kleinschreibung unterschieden.f
Wenn
f
der 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 f
sie 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 :)