Diese kleinen Tools sind z.B. für "kurz mal in einer Datei alle Doppelpunkte durch Semikolons ersetzen und dabei alles was dazwischen steht in Anführungszeichen einzuschließen" Jobs unheimlich praktisch. Ein paar Beispiele:

Shell-Ausgaben filtern

Man hat zuviele Kernel-Module kompiliert und will die überflüssigen, also die, bei denen Abhängigkeiten fehlen, löschen. Welche sind das?

 $ depmod -a
 /lib/blah/blubb/module.o: unresolved symbols
 (...)
 /lib/foo/bar/mymodule.o: unresolved symbols

Falls man davon sehr viele hat, ist es blödsinnig, die alle einzeln zu finden. Wozu hat man den UNIX-Werkzeugkasten? Also:

 depmod -a | cut -d: -f1 | xargs rm

cut "schneidet" aus dem Text den -f-ten Teil heraus, die Teile werden durch Tab oder den angegebenen DELIMITER (-d) getrennt. Hier wollen wir das "unresolved symbols" vergessen. xargs führt für jeden von STDIN gelesenen Dateinamen den angegebenen Befehl aus, hier rm -- töte sie! ;)

Das gleiche (prinzipiell) bewirkt folgender Befehl:

 rm `depmod -a | sed s/:.*$//`

oder

 rm $(depmod -a | sed s/:.*$//)

Hier wird das Feature der Shell benutzt, die Ausgabe von Programmen, die innerhalb von umgekehrten Anführungszeichen oder $(...) gesetzt werden, in die Kommandozeile mit zu übernehmen. sed -- der Stream Editor -- kriegt hier einfach nur folgendes zu tun: "lösche ab dem ersten Vorkommen von (:) ein beliebiges (.) Zeichen, und genau davon beliebig viele (*), und zwar bis zum Zeilenende ($)." (wobei das letzte eigentlich überflüssig ist). Die Ausgabe von diesem "depmod | sed" Konglomerat wird dann an rm übergeben, feddich is die Laube.

sed: der Stream Editor

Der Syntax von sed ist grundsätzlich

 sed s/altertext/neuertext/

Falls man ihn alles ersetzen soll (und nicht nur in jeder Zeile einmal), hängt man ein g direkt dahinter. Groß/Kleinschreibung ignorieren: i. Wenn in dem zu bearbeitenden Text Sonder- oder Leerzeichen vorkommen, muß man sie "escapen", vor der Shell schützen -- d.h. einen \ davor. oder sie in einfache (nicht umgekehrte!) Anführungszeichen packen.

'cut' kann auch spaltenweise arbeiten: Wir wollen aus jeder Zeile einer Datei Zeichen 11 bis 36 haben (der Rest soll weg). Bitte:

 cat datei.txt | cut -b11-36

Oder Spalte 11 bis 36 löschen:

 cat datei.txt | cut -b-11,36-

Ist doch eigentlich alles ganz einfach. :-)

Eine Einführung in sed mit vielen Beispielen - sogar auf Deutsch!

Kommentare löschen

Noch so ein Hammer: Wieder aus dem Usenet abgehört. Hier will jemand alle Linefeeds und alle Kommentare ({...}) durch ein Space ersetzen. Kein Problem. Hier ist es aber sinnvoll sich ein sed-script zu bauen, da man sowas nur umständlich direkt eingeben kann. Ich zitiere:

"Eine der Schwierigkeiten die Du vermutlich gehabt hast ist, dass Kommentare ({*}) ueber mehrere Zeilen gehen koennen. Da sed die Eingabe zeilenweise abarbeitet, hilft hier das Sammeln der gesamten Eingabe in den sogenannten Hold- Buffer. Dort kannst dann nach belieben tauschen (Ich gehe mal davon aus, dass eine Pascal-Source die Groesse des virtuellen Speichers nicht erreicht, von daher also keine weiteren Schwierigkeiten zu erwarten sind):

 H                   fuer alle Zeilen: Inhalt an Hold-Buffer anhaengen
 $ {                 bei der letzten Zeile:
   x                 Hold- und Patternbuffer austauschen
   s/{[[^}]*}/ /g     ersetze {, beliebige Zeichen ausser }, }, durch Space
   s/\n/ /g         "\n" durch Space
   p                 Patternbuffer ausgeben
   q                 fertig
 }

Aufruf:

 sed -n -f scriptdatei eingabedatei

Was jetzt noch nicht bedacht ist: Besteht eine Eingabezeile ausschliesslich aus Remark (Sie beginnt also mit "{" und endet mit "}"), so wird zuerst der Remark durch ein Space ersetzt, danach das "\n" der Vorzeile und das der akt. Zeile, so dass in diesem Fall ploetzlich drei Space auftauchen, wo vermutlich nur eines erwuenscht ist; ausgehend von meinem obigen Grundgeruest (welches ich uebrigens kaum getestet habe, soll ja nur ein Vorschlag sein ;-)) solltest das aber hinbekommen so wie Du es willst. Wenn nicht, NM :)

Angeblich soll sowas mit dem vi auch -- natürlich viiel einfacher -- gehen:

 :.;$s/^L/ /g
 :.;$s/|#/ /g

vi kann halt auch (mindestens) Kaffee kochen. ;-)

Ja, nu mein Gott, leg das Taschentuch wieder weg ... das ist doch nun wirklich nicht so schlimm ;-)

GnuTextUtilities (zuletzt geändert am 2007-12-23 22:48:41 durch localhost)