Mehrzeilig ersetzen

8

Ich habe ewig versucht, das herauszufinden. Zufällig muss ich es nicht mehr tun; Ich habe einen anderen Weg gefunden. Aber aus Gründen meiner geistigen Gesundheit würde ich die Antwort trotzdem gerne wissen.

Es ist ganz einfach, sedeinen Marker durch einen Text zu ersetzen. Was ich nicht herausfinden kann, ist, wie sedman einen großen Textblock mit komplexen Formatierungen wie mehreren Zeilen, Tabulatorzeichen usw. einfügt. Wie macht man das? Ist seddas Beste oder was?

MathematicalOrchid
quelle
1
Ich finde, dass Python & Regex bei komplexen mehrzeiligen Substitutionen viel flexibler sind als sed.
Tombolinux

Antworten:

3

Wenn Sie den Text an den Markierungen in einer Datei mit dem Namen /tmp/insert.txt einfügen möchten, können Sie diese Aufgabe wie folgt ausführen:

sed '/MARKER/ r /tmp/insert.txt' < inputfile

Der obige Befehl sed liest "Eingabedatei" und sucht nach MARKER. Wenn es gefunden wird, fügt es den Inhalt von /tmp/insert.txt in den Ausgabestream ein.

Wenn Sie möchten, dass der Marker selbst gelöscht wird, versuchen Sie Folgendes:

sed '/MARKER/ {s/MARKER//; r /tmp/insert.txt
}' <inputfile

Beachten Sie, dass vor der schließenden Klammer "}" eine neue Zeile stehen muss.

Wie im ersten Befehl arbeitet der sed auf Linien mit dem MARKER. Es ersetzt MARKER durch nichts und liest dann /tmp/insert.txt ein

Johan
quelle
3

Ich würde exfür diese Art von Aufgabe verwenden, es sei denn, Sie haben wirklich einen Datenstrom. Ich würde die exBefehle in einem Dokument hier aufbewahren:

ex $FILENAME << END_EX_COMMANDS
" Find the mark, assuming it's an entire line
/^MARKER$/
" Delete the marker line
d
" Add the complex, multi-line text
a
Complex, vividly formatted text here.
Even more "specially" formatted text.
.
" The '.' terminates the a-command. Write out changed file.
w!
q
END_EX_COMMANDS

Die Verwendung exist für vioder für vimBenutzer von Vorteil : Sie kennen die Tastenanschläge für die Befehle bereits, obwohl Sie das Gefühl haben, blind zu bearbeiten. Sie können auch mehrere Adds oder globale Ersetzungen vornehmen, alles, vimwas im ':' - Modus möglich ist.

Bruce Ediger
quelle
2

Ich glaube, dieser Befehl ist das, wonach Sie suchen:

r FILENAME
     As a GNU extension, this command accepts two addresses.

     Queue the contents of FILENAME to be read and inserted into the
     output stream at the end of the current cycle, or when the next
     input line is read.  Note that if FILENAME cannot be read, it is
     treated as if it were an empty file, without any error indication.

     As a GNU `sed' extension, the special value `/dev/stdin' is
     supported for the file name, which reads the contents of the
     standard input.
Serge
quelle
0

Hier ist eine vereinfachte Version von Bruce Edigers Antwort mit dem Änderungsbefehl, der eine Kombination aus Löschen und Anhängen darstellt.

ex $FILENAME << EOEX
/^MARKER$/c
The new text
to be inserted
here.
.
w!
q
EOEX
Gibies
quelle
0

Wenn Sie möchten, dass der Marker selbst gelöscht wird, versuchen Sie dies in einer Zeile:

sed -e '/MARKER/ r /tmp/insert.txt' -e '/MARKER/d' < inputfile

oder

sed -e '/MARKER/ {r /tmp/insert.txt' -e 'd }' < inputfile
Chen Deng-Ta
quelle