Das funktioniert mit gnu sed, ich glaube nicht, dass es auf gnu-spezifischen Erweiterungen beruht, aber ich weiß es nicht.
echo "$yourdata" | sed -ne '1; /^TAG1$/ } } }'
Ergebnis: alfa-bravo-charlie
Wie funktioniert es? Zuerst sagen wir sed "-n", dass wir nichts drucken wollen, wenn wir nicht ausdrücklich [p] rint sagen.
Der erste Block des sed-Ausdrucks ist "1 ". Dies besagt, wenn wir Zeile 1 lesen, diese Zeile in den [h] alten Puffer stapeln und dann [d] aus dem Arbeitspuffer löschen, so dass wir die nächste Zeile lesen und von Anfang an durch den sed-Ausdruck gehen.
Beim Lesen nachfolgender Zeilen wird der Block "1 {...}" übersprungen.
Wir passen nichts weiter zusammen, bis wir die Linie TAG1 erreichen. An dieser Stelle führen wir den langen {...} Block aus. Dies sagt, dass zuerst die [n] ext-Zeile gelesen wird, wodurch die TAG1-Zeile überschrieben wird, die sich im Puffer befand. Wenn der Puffer jetzt TAG2 ist, führen wir den nächsten inneren {...} - Block aus. Das liest zuerst die [n] ext-Zeile und überschreibt, was sich bereits im Puffer befindet. Die nächsten zwei Befehle sind "N; N". Lesen Sie die nächsten 2 Zeilen, aber fügen Sie sie hinzusie in den Arbeitspuffer, anstatt ihn zu überschreiben. Wenn der Arbeitspuffer jetzt mit / \ nTAG3 $ / übereinstimmt, führen wir den nächsten inneren {...} - Block aus. Das heißt zuerst "s ///", das heißt, ersetzen Sie den zuletzt übereinstimmenden Ausdruck durch die leere Zeichenfolge. Dadurch wird das "\ nTAG3" am Ende des Arbeitspuffers gelöscht und "\ nbravo" verlassen. Dann machen wir [H], was das an den Haltepuffer anhängt. ([h] überschreibt den Haltepuffer, [H] hängt daran an). Nun enthält der Haltepuffer die erste Zeile "alfa", dann die nächste Zeile "\ nbravo". Diese werden durch eine neue Zeile ergänzt, so dass wir wirklich "alfa \ n \ nbravo" haben. Wir werden uns später um die beiden Zeilen kümmern.
Wir machen weiter, bis wir "alfa \ n \ nbravo \ n \ ncharly" im Haltepuffer haben. Dann sagen wir [g] und den Haltepuffer (überschreiben, was sich im Arbeitspuffer befindet). Wir machen ein "s / \ n \ n / - /", um die doppelten Zeilenumbrüche in Striche zu verwandeln. Wir fügen am Ende des [s] -Befehls "g" - und "p" -Flags hinzu, so dass die Ersetzung global funktioniert (dh nicht nur eine Ersetzung dann stoppt) und dass das Ergebnis nach der Ersetzung [p] rinted ist.
Dann müssen wir den Rest des Eingabestroms nicht lesen.