GNU/Linux >> LINUX-Kenntnisse >  >> Linux

SED-Ersetzung über mehrere Zeilen hinweg

Lösung 1:

Sed arbeitet zeilenweise. Es kann so gemacht werden, dass es auf mehreren Zeilen funktioniert, aber es wurde nicht so konzipiert - und meiner Meinung nach zeigt es sich definitiv, wenn Sie versuchen, es so zu verwenden. Aber wenn Sie sich dafür entscheiden, müssen Sie wahrscheinlich Register verwenden. Sehen Sie sich einige der Lösungen unter https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n an, um zu sehen, wie es gemacht werden kann.

Ich ziehe es vor, für diese Art von Aufgabe perl statt sed zu verwenden (mehrzeilenorientiert, meine ich). Die Textbausteine, die Sie vor dem Suchen-und-Ersetzen einfügen müssen (BEGIN... ) ist nicht offensichtlich, aber die Regex erscheint mir sauberer:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Oder verwenden Sie die Gruppierung, um den Ausdruck zu verkürzen und Ihnen zu ermöglichen, dort einen regulären Ausdruck zu verwenden:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml

Es sollte sowohl bei Vorkommen mit als auch ohne Zeilenumbrüche zwischen den Kommentarmarkierungen und dem zu unkommentierenden Code funktionieren.

Angepasst von:

https://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

Lösung 2:

sed liest jede Zeile der Reihe nach, daher wird es niemals mit einem mehrzeiligen Muster übereinstimmen, es sei denn, Sie schieben es in die richtige Richtung. Die N Der Befehl liest eine Zeile aus der Eingabe und hängt sie an den Musterbereich an.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Wohl, wenn Sie einen anderen Befehl als s benötigen , dann sollten Sie von sed weg und zu awk oder perl wechseln. Hier ist ein etwas flexiblerer Perl-Schnipsel, der mit mehrzeiligen Kommentaren allgemeiner umgeht.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml

Lösung 3:

Hier ist eine Beschreibung der mehrzeiligen Befehle in SED:http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

Es ist ein Schmerz im Hintern. Vielleicht möchten Sie Eduardos Rat befolgen und perl -i -p -e verwenden stattdessen.

Lösung 4:

  • /<\!--/ :passende Zeichenfolge
  • :X :Dies ist ein Label für den Verzweigungsbefehl "b"
  • /-->/ :passende Zeichenfolge
  • [email protected]@[email protected] :"" entfernen und Ergebnis drucken
  • d :Musterbereich löschen und neuen Zyklus beginnen
  • N :wenn keine Übereinstimmung mit /-->/, dann füge eine Zeile hinzu
  • bX :zu :X Label verzweigen
  • p :Gib einfach einen String aus, der nicht mit /