Mit sed kann man auch Dateien lesen und schreiben.
Das geht mit den Kommandos 'r
filename
' und 'w
filename
'.
Beim Lesen wird die Datei nach dem gegenwärtigen Zyklus ausgegeben, oder wenn eine neue Zeile gelesen wird.
Eine nicht vorhandene Datei wird als existent aber leer angesehen. Der Befehl 'w
' legt eine neue
Datei an oder überschreibt eine schon vorhandene Datei und füllt sie mit dem
Inhalt des pattern space. Das Kommando 'w
' kann auch als
Flag zu 's///
' angegeben werden, wobei in die Datei geschrieben wird, wenn eine
Substitution erfolgen konnte.
Das folgende sed-Script ist ein Ersatz für den UNIX-Befehl 'tee dateiname',
sed -e 'w dateiname'
und wenn man es in der Form 'sed wdateiname
' schreibt, nur um ein 'w' länger als die
Version mit tee
Um den Einsatz des Kommandos 'r
' zu demonstrieren möchte ich meinen
Tante Amalien-Emulator vorstellen (der von Joseph Weizenbaums genialem
ELIZA inspiriert ist). Meine Tante Amalie hat 3 Standardsätze, die sie der
Reihe nach verwendet. Diese sind 'Meinst du?', 'Früher war es besser - entschieden besser!' und
'Davon verstehst du nichts.'.
Diese in die 3 Dateien stdsatz1
- stdsatz3
geschrieben ergeben mit
dem (unportablen!) Script
#!/bin/sed -nf 1~3r stdsatz1 2~3r stdsatz2 3~3r stdsatz3
das interessante Gespräch
Schönes Wetter heute Meinst du? Ja natürlich. Schau doch raus! Früher war es besser - entschieden besser! Ich weiß nicht was du hast - blauer Himmel und strahlender Sonnenschein. Davon verstehst du nichts. Wie du meinst, Amalie. Meinst du?
usw. Ich könnte mich stundenlang mit Amalie unterhalten. Für komplexere Charaktere wäre es denkbar,
den Input nach bestimmten Mustern zu durchsuchen und dementsprechend zu reagieren.
Dabei muss ja nicht jede Antwort in einer Datei gespeichert sein, man könnte ja den
pattern space mit 's/^.*$/Antwort/p
' füllen.
sed kennt noch einige meines Erachtens recht exotische Befehle wie
'a
', 'i
' und 'c
', welche einen gegebenen Text
ausgeben oder 'w
', welcher den pattern space in eine Datei schreibt
und noch derer mehr.
Sollten diese gebraucht werden, dann gibt die info-page bereitwillig Auskunft dazu.
Carlos Jorge G.duarte emuliert in seinem Tutorial sehr viele UNIX-Befehle mit
sed. Das mag als Beispiel sehr interessant sein (und ich empfehle jedem, diese
Programme anzuschauen und zu verstehen), ist aber in der Praxis zu kompliziert.
sed eignet sich durch die kompakte Schreibweise seiner Scripte besonders gut
für Einzeiler - wird das Problem größer, kann das Debuggen eines sed-Scriptes
sehr nervenaufreibend sein.
Eine sehr gute Alternative ist da awk, das eine ähnliche Syntax
(/regex/{action}
) unterstützt, darüber hinaus noch strukturierte Programme
(mit Konstrukten wie 'if (expr) statement else statement'
oder
'while (expr) statement
' u.Ä.) erlaubt, Funktionen zur Mustersuche, eigene Typen zur
Behandlung von Gleitkommazahlen und vieles mehr besitzt. Leider kennt es die sehr bequemen '\1
'
Referenzen nicht, die sed bietet. awk-Programme sind in der
Regel 3-10 mal so groß wie sed-Scripte.
Python oder perl bemüht man für größere und komplexere Probleme. Damit kann man ausgewachsene Programme schreiben, die zur Laufzeit interpretiert werden, wodurch sie etwas langsamer als sed- oder awk-Scripte abgearbeitet werden. Die Scripte können ungefähr die 8-40-fache Größe eines äquivalenten sed-Scriptes haben. Das muss kein Nachteil sein, denn die verlorene Zeit die ein mittelmäßiges Python-Script zur Laufzeit gegenüber einem sed-Script verliert, ist meistens durch eine lange Fehlersuche während des Schreibens eines solchen mehr als wettgemacht.
Keines dieser Tools soll verwendet werden, wenn das Betriebssystem ein dediziertes Programm für das jeweilige Problem bereitstellt, da dieses meist schneller und sicherer arbeitet und obendrein noch einfacher zu bedienen ist. UNIX bietet eine Vielzahl solcher Helferchen, die aber meistens nur einseitig oder überhaupt nicht verwendet werden. Ein Blick in die man-pages zu bash/tcsh, xargs, tr, test/[, cat/tac, cut, [ef]grep, uniq, sort, wc, tail, column/colrm, paste, look, hexdump, basename und Kumpanen, seq, luser, lart, whack, bosskill, [...] kann dem geneigten Leser nur zum Nutzen gereichen.
Das am meisten verbreitete Programm, in dem man sed-Anweisungen angeben kann, ist sicher vi. Um beispielsweise in einer Zeile "bla" nach "blupp" zu ändern, schreibt man
:s/bla/blubb/g
Ein interessantes Flag zum s///
-Kommando ist c
, welches bewirkt, dass man bei
jeder potentiellen Substitution um Bestätigung gefragt wird.
Ein Blick in die Dokumentation von vi (vim) zu weiteren
sed-Kommandos lohnt sich.
ed ist ein vollständiger Editor, und älter als sed. ed ist die richtige Wahl, wenn man Texte inline-editieren will. Zu beachten ist, dass, im Gegensatz zu sed, die Datei nicht tumb einmal von oben nach unten durchgeackert und eine Anweisung damit auf alle Zeilen angewandt wird. Das Kommando
s/bla/blupp/g
wird in ed nur auf die aktuelle Zeile angewandt. Der gewünschte Effekt wird mit
%s/bla/blubb/g
erreicht.
Ein anderes neues Kommando ist g/re/command
.
Es wendet das Kommando auf alle jene Zeilen an, auf welche der reguläre Ausdruck 're' passt.
Ein Beispiel dafür ist g/re/p
, welche alle Zeilen ausgibt, welche auf die RE passen.