Programmierung
Ersetzungen
Zu einem unixoiden System, wie es auch Linux und Mac OS X sind, gehört unbedingt eine Shell. Sicher gibt es Anwender (vielleicht die meisten), die noch nie eine Befehlszeile in eine Shell getippt haben, und lieber die Finger davon lassen. Es ist auch leicht, sich hier die Finger zu verbrennen, denn alles wird ohne Nachfrage einfach durchgeführt. Doch kann diese Schnittstelle das alltägliche Leben mit dem Computer erheblich vereinfachen, wozu schon ein kleines Vokabular ausreicht. Eine textbasierte Schnittstelle hat den Vorteil, dass sich sehr viel in eine Zeile packen lässt, was in einer grafischen Oberfläche viele Klicks voneinander entfernt ist. Eine Suche nach Dateien oder die Verarbeitung einer großen Anzahl von Dateien wird so leichter und eleganter durchgeführt. Und schließlich gibt es Dinge, die überhaupt nur über die Befehlszeilenschnittstelle bzw. mit Shell-Programmierung möglich sind.
Von allen Shells ist die Bash (Bourne-again shell) die verbreiteste und beliebteste. Eines der Konzepte, die sie zu einem ungemein flexiblen Werkzeug machen, ist die Substitution, die Ersetzung eines Feldes oder Ausdruckes durch das Ergebnis einer Berechnung oder durch den Rückgabewert eines Programmaufrufes. Bei der Syntax kommt es auf jedes Zeichen an, mitunter auch auf Leerzeichen – was eine konzise und kompakte Sprache ergibt.[1] Dabei kennt sie auch Toleranzen, wie die bezüglich des Zeichenkettenendes: Der Ausdruck ${Z:4:100}
z.B. wird durch hundert Zeichen nach den ersten vier ersetzt oder durch weniger, wenn nicht so viele Zeichen in der Variable Z
stecken (möglicherweise keine), also z.B.
$ Z=vierhundert
$ echo ${Z:4:100}
hundert
Die Syntax scheint manchmal zunächst etwas spitzfindig, ist bei näherem Hinsehen aber doch logisch und dann nicht schwer zu merken. Ein Ausdruck der Form ${string%substring}
entfernt die kürzeste Übereinstimmung mit substring
vom Ende von string
, wie z.B. hier ein e und beliebige auf das e folgende Zeichen (durch ein Sternchen angegeben):
$ echo ${Z%e*}
vierhund
In der Form ${string%%substring}
, mit doppeltem Prozentzeichen, wird die längste Übereinstimmung am Ende entfernt:
$ echo ${Z%%e*}
vi
Um das gleiche am Anfang einer Zeichenkette durchzuführen, schreiben wir das Nummerzeichen (auch Lattenzaun oder Hash genannt). (Woher dies kommt, erkennt übrigens, wer auf einer Tastatur mit englischem Layout die Tasten ‚#‘, ‚$‘, ‚%‘ nebeneinander liegen sieht.) Demnach benutzen wir die Form ${string#substring}
um die kürzeste Übereinstimmung und ${string##substring}
um die längste Übereinstimmung mit substring
vom Anfang von string
zu entfernen:
$ echo ${Z#*e}
rhundert
$ echo ${Z##*e}
rt
Das Sternchen, den Zeichen-Joker, setzen wir dabei vor das e, um beliebige vor ihm stehende Zeichen mitzunehmen (oder vielmehr wegzunehmen).
Die obigen Beispiele sind eher abstrakt. Das folgende, bei dem es darum geht, Dateien zu finden (und gegebenenfalls anders abzulegen), ist etwas konkreter: Eine Schleife, welche die Namen der Dateien in einem Verzeichnis Pictures (und seinen Unterverzeichnissen) unterhalb des Benutzerverzeichnisses ausgibt, die der Endung nach Canon-Camera-Raw-Daten enthalten (*.cr2).
$ for F in `find ~/Pictures -name "*.cr2"`; do echo ${F##*/}; done
Die schrägen einfachen Anführungszeichen umschließen eine Befehlssubstitution. Der Aufruf des Programms find
wird durch das Ergebnis ersetzt, die Liste der gefundenen Dateien, über die wir in einer for
-Schleife iterieren. (Der Schleifeninhalt wird durch do
und done
umschlossen.) Die Befehlssubstitution ist der Grund dafür, das Befehlszeilenprogramme in unixoiden Systemen einfach nichts ausgeben, wenn das Ergebnis leer ist, und auch sonst nichts Überflüssiges.
Mit der Substitution ${F##*/}
(die alles bis zum letzten Schrägstrich entfernt, also den Verzeichnispfad) könnten wir, statt sie einfach mit echo
auszugeben, beispielsweise in einem anderen Verzeichnis nach Duplikaten suchen (find ~/Pictures2 -name "${F##*/}"
).