Kapitel 7. Vermischtes

Dateien

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.

Noch mehr Kommandos

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.

sed oder nicht sed?

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.

Andere Programme mit sed-Kommandos

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.

Anmerkung

Eine geschichtliche Randnotiz: das UNIX-Kommando grep wurde bequemlichkeitshalber aus ed extrahiert, und der Name deutet an, was das Programm tut: global, Regular Expression, print.