Ich habe einige Beispiele dafür gesehen, aber in meiner speziellen Situation kriege ich es einfach nicht hin. Nehmen wir an, es gibt die folgende Datei.
foo
line 1
line 2
line 3
bar
junk
junk
foo
line 1
line 2
baz
line 4
bar
Ich versuche, alles zwischen „foo“ und „bar“, solange es „baz“ enthält, mit einer Einzeiler abzufangen.
Alles, was ich bisher gefunden habe, ist großartig, um alles zwischen foo und bar zu finden, aber nichts scheint gut zu sein, um es nur zu finden, wenn es baz enthält.
Bearbeiten: Folgendes funktioniert bei mir:
sed -n '/foo/{:a;N;/bar/!ba; /baz/p}' input.txt
Antwort1
awk '
/foo/ { save=1 }
/baz/ { p=1 }
/bar/ { if (p) { print out ORS $0; } p=0; save=0; out="" }
{ if (save) { if (out) { out = out ORS $0 } else { out = $0 } } }
' input
Beginnen Sie mit dem Speichern von Zeilen, wenn wir ein /foo/ sehen. Entscheiden Sie, dass es sich lohnt, sie auszudrucken, wenn wir ein /baz/ sehen. Sobald wir ein /bar/ sehen, drucken Sie die gespeicherten Zeilen aus, wenn wir ein /baz/ gesehen haben.
Ich kann keine intelligentere Möglichkeit finden, die Anzeige einer Leerzeile (ORS) am Anfang der Variable „out“ zu verhindern, ohne dies manuell zu testen (wie ich es tue).