Ich muss einen großen Textblock (Shell-Skriptcode) in einer Datei durch einen anderen Textblock ersetzen.
Ich bin beeindruckt von Wie kann ich sed verwenden, um eine mehrzeilige Zeichenfolge zu ersetzen? beantwortet von antak und Multi-Line-Ersatz beantwortet von Bruce Ediger
Aber ich habe einige Probleme damit.
antak hat bereits in seiner Antwort erwähnt, dass das Streaming der gesamten Datei (
1h;2,$H;$!d;g;
) in den Puffer für große Dateien nicht ratsam ist, da dadurch der Speicher überlastet wird.Ich weiß,
sed
dass mit der Blockfunktion der Text außerhalb des Blocks unverändert beibehalten werden kann. Ich möchte diese Funktion verwenden. Aber wenn ich benutze,sed -i '/marker1/,/marker2/s/.*/new text (code)/' filename
Für jeden Stream wird wiederholt neuer Text (Code) eingefügt. Daher muß ich den visuellen Block als einen Strom machen, etwas mit ähnlich zu dem, was vorgeschlagen Antak früher, aber für den Block (nicht für ganze Datei).
Wie von Bruce Ediger erwähnt, kann die Append-Funktion ausprobiert werden,
ex
die mita
end with.
(dot) beginnt , aber mein neuer Text (code) enthält Zeilen, die mit dot beginnen, was als Punkt der Append-Syntax betrachtet werden kann. Wie kann ich es in dieser Situation verwenden?ex
'sdd
' Anzahl der Zeilen 'kann mehrere Zeilen löschen, aber wenn ich einen Block zwischen / marker1 / und / marker2 / habe, dessen Anzahl nicht festgelegt (variierend) ist, muss er durch neuen Text (Code) ersetzt werden es?
sed
oder derex
Befehl funktioniert).r
den Befehl read file verwendet, um den Text aus einer anderen Datei zu kopieren, wenn sich die Quelle für den Ersatztext in einer Datei befindet.Antworten:
Ich schlage vor , mit dem c hange - Befehl (die im wesentlichen a d elete mit einem gekoppelten einem PPEND, obwohl die append nur für die letzte Zeile in dem Bereich, der genau angewandt wird , was Sie wollen hier):
Hier wird die
sed
Syntax von GNU für die direkte Bearbeitung verwendet (-i
). Dieserc
Befehl ist ansonsten Standard und portabel. GNUsed
unterstützt:als nicht standardmäßige Erweiterung.
Zeilenumbrüche und Backslash-Zeichen müssen im Ersatztext (mit Backslash) maskiert werden.
quelle
sed
als auch für alleex
gleichermaßen. Vielen Dank.sed
wie im Fall derex
von Bruce Ediger in " Mehrzeiliges Ersetzen" vorgeschlagenen Syntax .r
Befehl verwenden, der in anderen Antworten auf diese Frage beschrieben wird. Ich bin mir nicht sicher, wie Sie ein Dokument hier verwenden würdensed
.Mit GNU sed
So ersetzen Sie Zeilen, die eine Zeilenübereinstimmung beginnen
3
und mit einer Zeilenübereinstimmung fortfahren5
mitNew Code
:Bei Zeilen im Bereich
/3/,/5/
testen wir, ob die Zeile übereinstimmt5
(was bedeutet, dass dies die letzte Zeile in der Gruppe ist), und wenn ja, ersetzen wir sie durch EinfügenNew Code
. Wenn die Ersetzung vorgenommen wurde, weist dert
Befehl sed an, zum Ende der Befehle zu springen (in diesem FallNew Code
wird gedruckt). Wenn nicht, weist derd
Befehl sed an, die Zeile zu löschen.Alle anderen Zeilen werden normal gedruckt.
Um die Datei an Ort und Stelle zu ändern, kann die
-i
Option verwendet werden:Mit awk
So machen Sie dasselbe mit awk:
Der Befehl awk behandelt Zeilen im Bereich
/3/,/5/
speziell. Bei Zeilen in diesem Bereich testen wir, obf
Null ist (dh ob dies der!f
Fall ist). Wenn dies der Fall ist, drucken wirNew Code
und setzenf
auf 1. Anschließend überspringen wir den Rest der Befehle und springen zurnext
Zeile.Bei Zeilen außerhalb des Bereichs
/3/,/5/
wird kein Sprung ausgeführt, und1
die Zeile wird gedruckt. Im Detail1
ist eine Bedingung. Da1
nicht Null ist, wird die Bedingung als wahr ausgewertet. Da der Bedingung keine Aktion zugeordnet ist, wird die Standardaktion ausgeführt, bei der die Zeile gedruckt wird. Daher1
ist die Abkürzung für Print-the-Line.Um eine Datei an Ort und Stelle zu ändern, kann die
-i inplace
Option mit GNUawk
4.1 oder höher verwendet werden:quelle
awk
, könnten Sie bitte etwas Ihrenawk
Ausdruck erklärensed '/3/,/4/d;/5/cNew Code'
awk '/5/{print "New Code"}/3/,/5/{next}1'
Basierend auf der obigen Diskussion habe ich eine Lösung mit
ex
Das obige gibt
Vielen Dank an g-man , dass er mich auf den Änderungsbefehl aufmerksam gemacht und Klarheit über dot gegeben hat. Beide
sed
und haben eineex
fast ähnliche Syntax für den Änderungsbefehl (auch für den Löschbefehl, den Befehl zum Anhängen usw.).quelle