Wie kann ich den gesamten Text in geschweiften Klammern in einer mehrzeiligen Textdatei löschen?

10

Beispiel:

This is {
the multiline
text file }
that wants
{ to be
changed
} anyway.

Soll werden:

This is 
that wants
 anyway.

Ich habe einige ähnliche Themen im Forum gefunden, aber sie scheinen nicht mit mehrzeiligen geschweiften Klammern zu funktionieren.

Wenn möglich, würde ich eine einzeilige Methode bevorzugen, wie Lösungen, die auf grep, sed, awk ... usw. basieren.

BEARBEITEN: Lösungen scheinen in Ordnung zu sein, aber ich habe festgestellt, dass meine Originaldateien verschachtelte Klammern enthalten. Also öffne ich eine neue Frage. Vielen Dank an alle: Wie kann ich den gesamten Text zwischen verschachtelten geschweiften Klammern in einer mehrzeiligen Textdatei löschen?

Sopalajo de Arrierez
quelle
1
Versuchen Sie diessed '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

Antworten:

10
$ sed ':again;$!N;$!b again; s/{[^}]*}//g' file
This is 
that wants
 anyway.

Erläuterung:

  • :again;$!N;$!b again;

    Dadurch wird die gesamte Datei in den Musterbereich eingelesen.

    :againist ein Etikett. Nliest in der nächsten Zeile. $!b againverzweigt zurück zum againEtikett, sofern dies nicht die letzte Zeile ist.

  • s/{[^}]*}//g

    Dadurch werden alle Ausdrücke in geschweiften Klammern entfernt.

Versuchen Sie unter Mac OSX:

sed -e ':again' -e N -e '$!b again' -e 's/{[^}]*}//g' file

Verschachtelte Klammern

Nehmen wir dies als Testdatei mit vielen verschachtelten Klammern:

a{b{c}d}e
1{2
}3{
}
5

Hier ist eine Modifikation für verschachtelte Klammern:

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file2
ae
13
5

Erläuterung:

  • :again;$!N;$!b again

    Dies ist das gleiche wie zuvor: Es liest die gesamte Datei ein.

  • :b

    Dies definiert eine Beschriftung b.

  • s/{[^{}]*}//g

    Dadurch wird Text in geschweiften Klammern entfernt, solange der Text keine inneren Klammern enthält.

  • t b

    Wenn der obige Ersatzbefehl zu einer Änderung geführt hat, kehren Sie zur Bezeichnung zurück b. Auf diese Weise wird der Ersatzbefehl wiederholt, bis alle Klammergruppen entfernt sind.

John1024
quelle
Ihre Antwort scheint perfekt zu sein. Solange die neue Frage, die ich gerade geöffnet habe (Originalfrage lesen EDIT), nicht genau dieselbe ist, sollten Sie sie auch beantworten. Wäre es in Ordnung mit den Forumregeln?
Sopalajo de Arrierez
@ John1024, Sie können Ihre Bearbeitung hierher verschieben, da das OP eine neue Frage dazu gestellt hat.
Ramesh
1
IN ORDNUNG. Ich habe es dort kopiert und geändert, um den Beispieltext in der neuen Frage zu verwenden.
John1024
5

Perl:

perl -0777 -pe 's/{.*?}//sg' file

Wenn Sie direkt bearbeiten möchten

perl -0777 -i -pe 's/{.*?}//sg' file

Dadurch wird die Datei als einzelne Zeichenfolge gelesen und global gesucht und ersetzt.

Dies behandelt verschachtelte Klammern:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'
Glenn Jackman
quelle
Danke, das war sehr hilfreich! Dies hat mir geholfen, ein Problem mit einem Build-Skript zu lösen, das den Inhalt einer Funktion innerhalb von Minuten ersetzt, anstatt mit sed mit ah..em zu kämpfen, mehr Zeit als ich zugeben werde (Stunden..husten..husten)
AndrewD
4

Sed:

sed '/{/{:1;N;s/{.*}//;T1}' multiline.file

seit Zeile mit gestartet {und die nächste Zeile ( N) abrufen, bis Substitution ( {}) vorgenommen werden kann ( Tbedeutet Rückkehr zur Markierung von, :wenn keine Ersetzung vorgenommen wurde)

Ein wenig modifizieren, um wahr zu sein, wenn viele Locken in einer Linie geklammert sind

sed ':1; s/{[^}]*}// ; /{/ { /}/!N ; b1 }' multiline.file

Entfernen Sie alle Symbole in den Klammern ( [^}]entspricht jedem Symbol,right bracket außer um sednicht gierig zu werden), und wenn in der Zeile verbleiben left bracked, beginnen Sie mit der nächsten hinzugefügten Zeile, wenn dies nicht der Fall ist right bracket.

Costas
quelle