AA_code.jpg

© Kheng Ho Toh, 123RF

Titelkampf

Dateilisten erzeugen und drucken

Wir feiern Premiere: Im ersten Bash-Workshop lesen Sie, wie Sie die Dateien eines Verzeichnisses auflisten, zurechtschnitzen und ausdrucken.

Spiegel Online schilderte neulich einen interessanten Fall, mit Dateien umzugehen: Der Vater eines Lesers wollte – unter Windows – eine Liste aller Dateien auf einer Diskette ausdrucken. Dazu öffnete er die Diskette im Windows Explorer, machte ein Bildschirmfoto und rief dieses dann in der Textverarbeitung Word auf. Von hier druckte er es aus, scannte den Ausdruck und ließ eine Texterkennung über das eingescannte Dokument laufen. Den so erkannten Text öffnete er erneut in Word, um ihn auszudrucken.

Es gibt definitiv elegantere Wege, solche Aufgaben zu erledigen, man muss sie allerdings kennen. Oft liefert die Internetsuche nur viele unvollständige oder zu komplizierte Lösungswege. Einer hätte darin bestanden, die Texterkennung direkt über das Bildschirmfoto laufen zu lassen. Eine andere Methode führt direkt zu unserem Thema, denn auch unter Windows gibt es eine eingebaute Kommandozeile: Der Befehl dir /b > dateien.txt schreibt hier die Namen der sichtbaren und versteckten Dateien im aktuellen Verzeichnis in eine Textdatei mit dem Namen dateien.txt. Die lässt sich dann ausdrucken.

An's Terminal!

Während aber der Einsatz der Kommandozeile unter Windows eine Ausnahme bleibt, machen routinierte Linux-Anwender regelmäßig Gebrauch von ihr. Zwar wollen die Ubuntu-Entwickler möglichst für alle Aufgaben grafische Tools basteln, aber über die Kommandozeile lassen sich einige Dinge schlicht schneller regeln – etwa das Einbinden externer Paketquellen. Wer zudem häufig wiederkehrende, monotone Arbeiten erledigen muss (etwa das Konvertieren von tausenden Bildern), dürfte an der Bash und ihren Skripten viel Freude haben.

Die Bourne-again shell (kurz Bash) stammt aus dem Jahr 1987 und ist eine Unix-Shell. Damit ist sie älter als der Linux-Kernel selbst, begleitet das freie Betriebssystem aber seit den Anfängen. Es gibt verschiedene Shells, die Sie nicht mit der Kommandozeile gleichsetzen dürfen. Sie laufen zwar in ihrer Umgebung, es handelt sich aber jeweils um eigene Interpreter. Dazu gehören die ksh (Korn Shell), zsh (Z-Shell) oder die klassische Bourne-Shell, von der die Bash ihren Namen ableitet. Sie beherrscht die meisten Funktionen der klassischen Bourne-Shell.

Kommandozeileninterpreter wie die Bash arbeiten u. a. Befehle und Funktionen ab. Einige davon sind direkt in die Bash eingebaut (Builtins), für andere startet sie externe Programme in Form separater Prozesse. Sobald Sie mehrere Eingaben nacheinander ausführen, um ein Problem zu lösen, lohnt es sich eigentlich, ein Bash-Skript anzulegen. Das machen Sie in einem Editor, indem Sie die Zeilen nacheinander anordnen. Rufen Sie das fertige Skript auf, wird die Bash aktiv und durchläuft es Zeile für Zeile. So lassen sich konkrete Aufgabe erledigen – selbst so einfache wie das Auflisten der Dateien im aktuellen Verzeichnis.

Der Editor

Um ein Shell-Skript zu verfassen, bemühen viele Anwender Kommandozeilen-Editoren wie pico, vim oder emacs. Der Vorteil: Diese findet man auf den meisten Linux-Systemen. Der Nachteil: Sie sind etwas umständlich zu bedienen, weil Sie erst eine Reihe von Tastenkombinationen erlernen müssen. Das lohnt sich zwar auf lange Sicht, wir benutzen für unsere Skripte aber dennoch Gedit, einen grafischen Editor mit integriertem Terminal-Plug-in.

Letzteres installieren Sie über das Paket gedit-plugins. Dann rufen Sie den Editor auf, indem Sie [Super] (Unity) oder [Alt]+[F2] (Gnome) drücken und gedit eintippen. Über Bearbeiten | Einstellungen | Plugins werfen Sie einen Blick auf die verfügbaren Erweiterungen und machen ein Kreuzchen bei Eingebettetes Terminal. Damit Ihr Editor so aussieht wie in Abbildung 1, speichern Sie das aktuelle Dokument unter dem Namen dateiliste1.sh (die Endung identifiziert die Datei deutlich als Skript). Dann wählen Sie Ansicht | Fußleiste, um das Terminal einzublenden. Wechseln Sie über den cd-Befehl in das Verzeichnis, in dem sich auch das neu angelegte Skript befindet.

Bevor Sie nun gleich am Skript arbeiten, müssen Sie einige Vorüberlegungen treffen und Tests vornehmen. Programmieren bedeutet häufig, ein großes Problem in viele kleine zu zerlegen. Was soll das Skript tun? Es soll zunächst einen Befehl aufrufen, der alle Dateien im aktuellen Verzeichnis auflistet. Diese Liste soll dann in einer Textdatei landen, die sich ausdrucken lässt. Um die Aufgabe etwas konkreter zu machen, knöpfen wir uns die Titel einer CD vor, die im MP3-Format vorliegt. Diese Liste wollen wir dann ausdrucken und in eine CD-Hülle kleben. Um alle Dateien im Verzeichnis anzuzeigen, genügt der schlichte Befehl ls. Da die Dateinamen bereits die Tracknummern und Titel enthalten, benötigen Sie keine weiteren Parameter (Abbildung 2).

Abbildung 1

Abbildung 1: Es gibt zwar einige Editoren für die Kommandozeile, der Einarbeitungsaufwand in diese ist allerdings recht hoch. Im Workshop verwenden wir daher Gedit mit Terminal-Plug-in.

Abbildung 2

Abbildung 2: Der Befehl "ls" zeigt alle im Verzeichnis enthaltenen Dateien an. Allerdings stören die MP3-Endungen auf der CD-Hülle, hier lässt sich nachbessern.

Was auf dem Ausdruck für die fertige CD stört, sind die MP3-Endungen. Diese entfernen Sie mit Hilfe des sed-Befehls. Tippen Sie

$ ls | sed -e 's/\.mp3$//g'

in das Terminal, erhalten Sie das Ergebnis aus Abbildung 3. Der Befehl sieht schon etwas komplizierter aus, lässt sich aber auch recht einfach erklären. Zunächst verketten Sie in der Zeile zwei Kommandos: ls und sed: Ersteres listet die Dateien auf (mit der MP3-Endung) und übergibt die Ergebnisse dann über eine Pipe () an das zweite Programm namens sed. Hier handelt es sich um einen so genannten Streameditor, mit dem Sie Zeichenketten bearbeiten. Über die Option -e hängen Sie einen Filter an sed, der zwischen einfachen Anführungszeichen steht und die Zeichenkette beschneiden soll.

Abbildung 3

Abbildung 3: Der Befehl ist kryptisch, das Ergebnis sieht sauberer aus: Jagen Sie die Dateinamen durch den Streameditor "sed", entfernt dieser die unerwünschten MP3-Endungen.

Tipp

Sed erwartet Dateien im UTF-8-Format. Bei ISO-8859-Dateien, die Umlaute oder andere Sonderzeichen enthalten, schneidet der Streameditor unter Umständen nur den Teil einer Zeile bis zum ersten Umlaut aus und bricht dann ab.

Was aber tut der kryptische Filter 's/\.mp3$//g'? Eine verständlichere Variante des Aufrufs sieht so aus: 's/Hallo/Wiedersehen/g'. Sie ersetzt in einem Text jedes Hallo durch ein Wiedersehen. Nach dem ersten Slash folgt dabei der Suchtext (Hallo), nach dem zweiten der Text, welcher den Suchtext ersetzt (also Wiedersehen).

Im Falle der mp3-Endung ersetzen Sie Hallo durch den regulären Ausdruck \.mp3$. Der Backslash (\) sorgt dafür, dass sed den Punkt als Suchtext interpretiert und nicht als Teil des regulären Ausdrucks (der dann stellvertretend für ein beliebiges Zeichen stünde). Dank des $-Zeichens am Ende sucht sed nach der Zeichenkette .mp3 und beendet die Suche erst am Ende der Zeile. Weil der Platz nach dem zweiten Slash (vor dem /g') leer bleibt, löscht sed alle Fundstücke, was zum Ergebnis aus Abbildung 3 führt.

Die Ausgabe des gesamten Kommandos leiten Sie nun über eine so genannte Umleitung in eine Textdatei namens titelliste.txt weiter:

$ ls | sed -e 's/\.mp3$//g' > titelliste.txt

Als Symbol für die Umleitung kommt die spitze Klammer zum Einsatz.

Tipp

Befindet sich bereits wichtiger Text in der Datei titelliste.txt, den Sie nicht löschen wollen, verwenden Sie zwei spitze Klammern (>>). In diesem Fall fügt die Bash die neuen Einträge hinter den vorhandenen Inhalten ein.

Sie sehen beim Abschicken des Befehls über [Eingabe] zwar keine Bildschirmausgabe, schauen sich die Früchte der Arbeit aber mit Hilfe von Gedit an. Seltsam nur, dass am Ende der Datei titelliste.txt auch ein Eintrag namens titelliste.txt steht. Das liegt daran, dass die Bash selbst zunächst prüft, ob die Zieldatei vorhanden ist und diese anlegt. Erst dann erstellt die Bash ihre Liste und schneidet die Dateiendungen ab.

Sie könnten die Datei nun einfach an einer anderen Stelle im Dateisystem – etwa im übergeordneten Verzeichnis – erzeugen. Alternativ blenden Sie Textdateien einfach aus den Suchergebnissen aus:

$ ls --hide "*.txt" | sed -e 's/\.mp3$//g' > titelliste.txt

Das erledigt die ls-Option --hide "*.txt". Wollen Sie die Ausgabe nicht nur in eine Datei umleiten, sondern zugleich auf dem Bildschirm ausgeben, hilft das kleine Tool tee:

$ ls --hide "*.txt" | sed -e 's/\.mp3$//g' | tee titelliste.txt

Über eine weitere Pipe geben Sie das Ergebnis dabei an tee weiter, das den Text sowohl in die Datei titelliste .txtschreibt, als auch auf den Bildschirm. Verwenden Sie tee -a titelliste.txt hängt das Programm die neuen Einträge an einen bereits vorhandenen Text.

Einem Freund empfehlen