Ich habe eine Hugh-Datei mit folgenden Details:
define host{
use generic-host ; Name of host template to use
host_name ServerA_172.29.16.102
alias ServerA_172.29.16.102
address 172.29.16.102
check_command check-host-alive
max_check_attempts 3
notification_interval 120
notification_period 24x7
}
define host{
use generic-host ; Name of host template to use
host_name ServerB_172.29.16.103
alias ServerB_172.29.16.103
address 172.29.16.103
check_command check-host-alive
max_check_attempts 3
notification_interval 120
notification_period 24x7
}
Was ich will, suche "address 172.29.16.102"
und lösche 4 Zeilen über und nach 5 Zeilen.
Ich habe versucht, mit sed zu folgen, aber nicht zu arbeiten
sed '$N;$N;N;/address 172.29.16.102/,+5d' hosts
text-processing
sed
Rahul Patil
quelle
quelle
sed -n '/\s*address/p;' file
wird es sicher gelöst? Welches ist das gleiche wiegrep 'address' file
? Oder fehlt mir hier etwas? Wie soll die Ausgabe aussehen?define {
zu ermitteln,}
ob diese Adresse übereinstimmt. Es sollte kein anderer Inhalt entfernt werden, das war'sAntworten:
Wenn jeder
define_host
Abschnitt durch einen oder mehrere Zeilenumbrüche getrennt ist, dann ist dies genau die Art von Problem des GNU awk mehrzeilige Rekord Unterstützung soll lösenquelle
172.29.16.102
? War es auch durch Leerzeilen klar von anderen Einträgen getrennt?Wann immer ich diese Art von Frage sehe, sagt mir mein Bauch, dass dies ein Job für ist
grep
. Diegrep
Fähigkeit,-v
die Ergebnisse bei Verwendung der Vorher- und Nachher-Schalter (-B ..
&-A ..
) umzukehren ( ), lässt dies jedoch nicht zu.Doch dieser clevere Ansatz des Aufrufs
grep
2 mal macht es viel sauberer als eine derawk
odersed
Lösungen , die ich bisher gesehen habe.Beispiel
Hier sind einige Beispieldaten.
Nun, wenn wir unseren Befehl ausführen:
quelle
Anstatt eine strenge Anzahl von Zeilen mit sed oder grep zu verwenden, würde ich lieber etwas schreiben, das eine grundlegende Interpretation des Dateiformats selbst vornimmt und den Inhalt jedes Datensatzes bewertet . Betrachten Sie Folgendes mit awk:
Die Idee hier ist, dass wir durch die Datei gehen und jedes Mal, wenn wir sehen
define host
, jede Zeile zur Variablen hinzufügenblob
. Wenn ein neuer Datensatz beginnt oder wenn wir am Ende der Datei angelangt sind, verarbeiten wir diese Variable mithilfe derdoit()
Funktion.Dies funktioniert sowohl in GNU als auch in Classic Awk.
quelle
Dies ist ein perfektes Beispiel dafür , warum
sed
ist der s tream ed itor, und wird nie die Kraft ersetztex
für in-Place - Datei bearbeiten.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. Undinput
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, deng
Befehl lobal zu verwenden und das-s
Flag zu verwenden, um die Ausgabe vonex
: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 deng
Befehl verwenden (um die Datei zu beenden, nachdem der erste Löschbefehl ausgeführt wurde). und geben Sieq!
unten einen Befehl ein, falls derg
Befehl mangels übereinstimmender Zeilen nicht ausgeführt wird.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 Bearbeitungssitzungex
, um dieses Update interaktiv durchzuführen, sieht ungefähr so aus:Die POSIX-Spezifikationen zur
ex
weiteren Lektüre.quelle
Was ist damit?
Es entfernt die bestimmten Zeilen, die nicht benötigt werden, wenn wir annehmen, dass es keine ähnlichen Zeilen in der Datei gibt, die wir nicht entfernen sollten.
quelle
Mit können
sed
Sie tun:... die jeden Block beim
H
Einlesen separat im alten Speicherplatz puffern und nur diejenigen drucken, die keine Übereinstimmung für Ihr Muster enthalten.quelle