Tipp: Regular Expressions mit sed 2
In diesem letzten Teil der Serie lernen wir weitere
Funktionen von sed
kennen.
Als Beispiel dient uns dieses Mal eine Konfigurationsdatei des
DHCP-Servers. Sie ist unter dem Namen dhcpd.conf
gespeichert und
enthält die eine oder andere Unstimmigkeit.
option domain-name-servers 172.16.1.1;
subnet 172.16.1.0 netmask 255.255.255.0 {
range 172.1.1.10 172.1.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option time-servers 172.16.1.1;
option lease-time 86400;
}
Im Artikel lassen wir sed
den geänderten Dateiinhalt ausgeben, gehen
aber davon aus, dass die Änderungen ebenfalls in die Datei geschrieben
werden und damit beim nächsten Aufruf vorhanden sind. Dieses Verhalten
erreichen wir mit der Kommandozeilenoption -i
, die wir
bereits im ersten Teil der Serie kennengelernt haben.
Bisher haben wir uns auf die ‘Substitution’ von Mustern im gesamten Text
beschränkt. Dabei kann sed
auch weiter eingeschränkt werden: Eine
Ziffer vor dem Kommando gibt die Zeile an.
Hier korrigieren wir in der vierten Zeile die IP-Adresse des Adressbereichs:
user@linux ~ $ sed '4s/172\.1/172.16/g' < dhcpd.conf
option domain-name-servers 172.16.1.1;
subnet 172.16.1.0 netmask 255.255.255.0 {
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option time-servers 172.16.1.1;
option lease-time 86400;
}
Alternativ erreichen wir dasselbe mit einem Pattern-Matching. Der Vorteil liegt auf der Hand: Diese Variante funktioniert auch dann noch, wenn sich die Zeile durch eine Einfügung verschiebt.
user@linux ~ $ sed '/range/ s/172\.1/172.16/g' < dhcpd.conf
Nun stellen wir fest, dass es in unserem Netzwerk
keinen Zeitserver gibt, die Option time-server
ist also nicht mehr notwendig und soll
ersatzlos gelöscht werden. Dazu dient das Kommanto
delete
, kurz d
:
user@linux ~ $ sed '/time-servers/d' < dhcpd.conf
option domain-name-servers 172.16.1.1;
subnet 172.16.1.0 netmask 255.255.255.0 {
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option lease-time 86400;
}
Dokumentation ist immer eine gute Sache. Mit dem
Kommando insert
, kurz i
, fügen wir eine ganze
Zeile vor dem betreffenden Muster ein.
user@linux ~ $ sed '/^subnet/i # Subnet block' < dhcpd.conf
option domain-name-servers 172.16.1.1;
# Subnet block
subnet 172.16.1.0 netmask 255.255.255.0 {
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option lease-time 86400;
}
Umgekehrt macht es das Kommando append
, kurz a
. Hier wird die
Zeile nach dem Muster eingefügt. Der Backslash markiert den Anfang des
Textes und ermöglicht damit führende Leerzeichen. Andernfalls
interpretiert sed
das erste druckbare Zeichen als erstes Zeichen.
user@linux ~ $ sed '/^subnet/a \ # Subnet block options' < dhcpd.conf
option domain-name-servers 172.16.1.1;
# Subnet block
subnet 172.16.1.0 netmask 255.255.255.0 {
# Subnet block options
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option lease-time 86400;
}
Nun wollen wir eine Konfigurationsoption löschen und durch eine neue
Zeile ersetzen. Auch dazu gibt uns sed
mit dem Kommando change
,
kurz c
, die Möglichkeit:
user@linux ~ $ sed '/lease-time/c \ option max-lease-time 86400;' < dhcpd.conf
option domain-name-servers 172.16.1.1;
# Subnet block
subnet 172.16.1.0 netmask 255.255.255.0 {
# Subnet block options
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option max-lease-time 86400;
}
Der Stream Editor sed
kann allerdings nicht nur mit
einzelnen Zeilen, sondern auch mit Bereichen umgehen. Start
und Ende der Bereichsdefinition werden von einem
Komma getrennt. Das Dollarzeichen nimmt eine
besondere Funktion ein und stellt die letzte Zeile,
also das Ende der Datei, dar.
user@linux ~ $ sed '3,$s/^\s\+/\t/' < dhcpd.conf
option domain-name-servers 172.16.1.1;
# Subnet block
subnet 172.16.1.0 netmask 255.255.255.0 {
# Subnet block options
range 172.16.1.10 172.16.1.254;
option broadcast-address 172.1.1.255;
option routers 172.16.1.1;
option max-lease-time 86400;
}
Hier hat sed
von der dritten bis zur letzten Zeile
alle führenden Leerzeichen durch ein Tab-Zeichen
ersetzt und damit die Datei übersichtlicher
formatiert.
Und auch für diesen Zweck können Muster eingesetzt werden. Statt feste Zeilenangaben nutzen wir Muster, die Anfang und Ende eines Blocks treffen:
user@linux ~ $ sed '/^subnet/,/^}$/s/^\s\+/\t/' < dhcpd.conf
Hoffentlich hat Ihnen die Reihe zum Thema Stream Editor sed
und
Reguläre Ausdrücke
gefallen. Die Möglichkeiten sind damit noch
lange nicht erschöpft, vielleicht konnten wir Sie aber
zum Ausprobieren animieren.