# Arbeiten mit sed

Mit einem 'normalen' Editor ist das Bearbeiten von Dateien etwas aufwändig. Datei laden, Position suchen, Text aendern, Datei speichern. Wie aufwändig dies ist, sieht man erst im Vergleich zum Streameditor sed.

Wenn wir z.B. die ersten drei Zeilen einer Datei loeschen wollen, gehen wir so vor:

<div id="bkmrk-sed--e-%271%2C3d%27-eingab"><div>```
sed -e '1,3D' eingabe.txt
```

</div></div>Wenn du dieses Beispiel mit einer echten Datei testest, wird dir vermutlich nicht gefallen, dass die Ausgabe nur auf dem Bildschirm erscheint. Also leiten wir die Standardausgabe auf eine Datei um:

<div id="bkmrk-sed--e-%271%2C3d%27-eingab-0"><div>```
sed -e '1,3D' eingabe.txt > ausgabe.txt
```

</div></div>Die Datei eingabe.txt bleibt unverändert. In ausgabe.txt wird der Inhalt von eingabe.txt ohne die ersten drei Zeilen geschrieben. Wenn Sie die letzte Zeile löschen wollen:

<div id="bkmrk-sed--e-%27%24d%27-eingabe."><div>```
sed -e '$D' eingabe.txt > ausgabe.txt
```

</div></div>Das Zeichen $ steht als für die letzte Zeile. Dieser Befehl würde also alles ab der 2. Zeile löschen:

<div id="bkmrk-sed--e-%272%2C%24d%27-eingab"><div>```
sed -e '2,$D' eingabe.txt > ausgabe.txt
```

</div></div>Statt der Zeilennummern können wir aber die Grenzen des Arbeitsbereichs auch mit regulären Ausdrücken festlegen. Der folgende Befehl löscht alles ab dem Auftreten von 'BEGIN' bis zum Auftreten von 'END':

<div id="bkmrk-sed--e-%27%2Fbegin%2Fend%2Fd"><div>```
sed -e '/BEGIN/END/D' eingabe.txt > ausgabe.txt
```

</div></div>Würde 'END' nicht gefunden, so würde sed bis zum Dateiende weiter löschen.

Zu guter Letzt wollen wir die Auswahl umkehren - es sollen z.B. alle Zeilen gelöscht werden, nur die letzte nicht:

<div id="bkmrk-sed--e-%27%24-%21-d%27-einga"><div>```
sed -e '$ ! D' eingabe.txt > ausgabe.txt
```

</div></div>Das geht natürlich auch mit regulären Ausdrücken:

<div id="bkmrk-sed--e-%27%2Fbegin%2Fend%2Fd-0"><div>```
sed -e '/BEGIN/END/D' eingabe.txt > ausgabe.txt
```

</div></div>Statt mit der Umleitung (&gt;) kann sed auch inline (direkt in der Datei) editieren. Dazu einfach den Schalter -i verwenden:

<div id="bkmrk-sed--i--e-%271%2C3d%27-ein"><div>```
sed -i -e '1,3D' eingabe.txt
```

</div></div>Einer Zeile einen String hinzufügen, die mit einem bestimmten String anfängt:

<div id="bkmrk-sed-%27%2F%5Euser_alias-ad"><div>```
sed '/^User_Alias ADMINS=/ s/$/,newadmin/' /etc/sudoers
```

</div></div>Zeile mit pattern +X nachfolgende Zeilen löschen:

<div id="bkmrk-sed--e-%27%2Fpattern%2F%2C%2B5"><div>```
sed -e '/pattern/,+5d' datei.txt
```

</div></div>Rekursive Verarbeitung verschiedenster Dateien:

<div id="bkmrk-find--type-f--name-%22"><div>```
find -type f -name "*.conf" -print0 | xargs -0 sed -i 's#http_certificate = "30,14"#http_certificate = "14,7"#'
```

</div></div>Einen String mit vorgestelltem Prefix „verdoppeln“:

<div id="bkmrk-%23-beispielliste-mit-"><div>```
# Beispielliste mit Domainnamen. domainliste.txt enthält:
1lik28pvitfl8q9o0jh.de
li816ifohpxhwfuj0d5.de
v6rhv3hwx3w9cgd4syi.de
gxxkz832p71j6hujron.de
aen9nldoy5wds640yg5.de
okzi8954w6ihsbcvai8.de
```

</div></div>Mit diesem Kommando wird jede Zeile verdoppelt, mit Leerzeichen getrennt und dem ersten Eintrag ein www. vorangestellt:

<div id="bkmrk-cat-domainliste.txt-"><div>```
cat domainliste.txt | sed 's/\<.*\>/www.& &/'

www.1lik28pvitfl8q9o0jh.de 1lik28pvitfl8q9o0jh.de
www.li816ifohpxhwfuj0d5.de li816ifohpxhwfuj0d5.de
www.v6rhv3hwx3w9cgd4syi.de v6rhv3hwx3w9cgd4syi.de
www.gxxkz832p71j6hujron.de gxxkz832p71j6hujron.de
www.aen9nldoy5wds640yg5.de aen9nldoy5wds640yg5.de
www.okzi8954w6ihsbcvai8.de okzi8954w6ihsbcvai8.de
```

</div></div>Mit tr läßt sich noch der Zeilenumbruch in ein Leerzeichen umwandeln. Nützlich um z.B. aus einer Domainliste einen Eintrag für die /etc/hosts zu generieren:

<div id="bkmrk-cat-domainliste.txt--0">```
cat domainliste.txt | sed 's/\<.*\>/www.& &/' | tr '\n' ' '

www.1lik28pvitfl8q9o0jh.de 1lik28pvitfl8q9o0jh.de www.li816ifohpxhwfuj0d5.de li816ifohpxhwfuj0d5.de www.v6rhv3hwx3w9cgd4syi.de v6rhv3hwx3w9cgd4syi.de [...]
```

</div>