Dies ist ein perfektes Beispiel dafür , warum sed
ist der s tream ed itor, und wird nie die Kraft ersetzt ex
für in-Place - Datei bearbeiten.
ex -c '/address *172.29.16.103/
?{?,/}/d
x' input
Dieser Befehl ist eine vereinfachte Form, die nicht so robust ist, wie sie sein könnte, sondern zur Veranschaulichung dient.
Der erste Befehl findet den angegebenen regulären Ausdruck und bewegt den Cursor in diese Zeile.
Der zweite Befehl besteht aus zwei durch Komma getrennten Adressen, auf denen der d
Befehl elete ausgeführt wird. ?{?
Sucht von der aktuellen Zeile rückwärts nach einer offenen geschweiften Klammer und /}/
von der aktuellen Zeile nach einer engen geschweiften Klammer vorwärts. Alles dazwischen wird gelöscht (zeilenweise, sodass auch der Anfang der offenen geschweiften Klammer gelöscht wird).
x
speichert die Änderungen und beendet. Und input
ist natürlich der Name der Datei.
Für die von Ihnen eingegebene Eingabe funktioniert dieser Befehl genau wie gewünscht.
Nun erwähnte ich, dass dies erheblich verbessert werden könnte. Wir werden mit dem regulären Ausdruck beginnen. Das offensichtlichste Ergebnis hierbei ist, dass Perioden Platzhalter sind. Der angegebene reguläre Ausdruck könnte auch mit "172329-16 103" übereinstimmen. Daher müssen die Punkte mit umgekehrten Schrägstrichen versehen werden, damit sie nur mit wörtlichen Punkten übereinstimmen.
Als nächstes kommt das Leerzeichen. Ich habe zwei Leerzeichen gefolgt von einem * eingefügt (ich hätte verwenden können, \+
aber ich weiß nicht, ob diese Funktion in POSIX erforderlich ist), aber was ist, wenn die Datei Tabulatoren enthält? Die beste Lösung ist zu verwenden [[:space:]]
. (Das würde viel besser aussehen \+
; wenn jemand herausfindet, ob das POSIX ist, schreibe bitte einen Kommentar.)
Was ist, wenn der reguläre Ausdruck nicht in der Datei gefunden wird? Nun, dann wird die Datei einfach zum Bearbeiten geöffnet und der Befehl "Suchen" schlägt fehl, und eine Fehlermeldung wird gedruckt und der Rest der angegebenen Befehle wird nicht ausgeführt - Sie bleiben im ex
Editor So können Sie Änderungen von Hand vornehmen. Wenn Sie jedoch die Änderungen in einem Skript automatisieren wollen, möchten Sie wahrscheinlich den Editor Ausgang , wenn keine Änderungen vorgenommen werden müssen. Die Antwort besteht darin, den g
Befehl lobal zu verwenden und das -s
Flag zu verwenden, um die Ausgabe von ex
:
ex -sc 'g/address[[:space:]][[:space:]]*172\.29\.16\.103/ ?{?,/}/d
x' input
Dies entspricht nicht ganz dem früheren Befehl. Wenn es mehr als einen geschweiften Klammerblock mit einer übereinstimmenden Linie gibt, löscht der globale Befehl hier alle. Das ist wahrscheinlich was du sowieso willst.
Wenn Sie beim Beenden nur die erste Übereinstimmung löschen möchten, ohne die Datei zu ändern, wenn überhaupt keine Übereinstimmungen vorhanden sind, können Sie den x
Befehl als Teil des Arguments für den g
Befehl verwenden (um die Datei zu beenden, nachdem der erste Löschbefehl ausgeführt wurde). und geben Sie q!
unten einen Befehl ein, falls der g
Befehl mangels übereinstimmender Zeilen nicht ausgeführt wird.
ex -sc 'g/address[[:space:]][[:space:]]*172\.29\.16\.103/ ?{?,/}/d | x
q!' input
Um ehrlich zu sein, lassen diese Befehle den Prozess viel komplizierter aussehen als er ist. Die Robustheit geht zu Lasten der extremen Klarheit und Lesbarkeit des Codes. Es ist ein Kompromiss.
Ich empfehle, einige Dateien interaktiv ex
zu bearbeiten , um ein Gefühl dafür zu bekommen. Auf diese Weise können Sie sehen, was Sie tun. Eine solche Bearbeitungssitzung ex
, um dieses Update interaktiv durchzuführen, sieht ungefähr so aus:
$ ex input
"input" 23L, 843C
Entering Ex mode. Type "visual" to go to Normal mode.
:/103
host_name ServerB_172.29.16.103
:?{?,/}/d # This deletes the current block
:$p # Print and move to last line
:-5,.p # Print some more lines to check result
notification_interval 120
notification_period 24x7
}
:?}?+,.d # Trim whitespace
}
:x # Save and exit
$
Die POSIX-Spezifikationen zurex
weiteren Lektüre.