Home / LinuxUser / 2001 / 10 / The Answer Girl

Newsletter abonnieren

Lies uns auf...

Folge LinuxCommunity auf Twitter

Top-Beiträge

Mandriva gibt Distribution in die Hände der Community
(268 Punkte bei 24 Stimmen)
Neues vom Systemd
(161 Punkte bei 4 Stimmen)
Mandriva in Nöten
(161 Punkte bei 4 Stimmen)

Heftarchiv

LinuxUser Heftarchiv

EasyLinux Heftarchiv

Ubuntu User Heftarchiv

Ubuntu User Heftarchiv

Partner-Links:

Shopping
Topsuche
 
Yatego Deutschlands größte Shoppingmall. 10000 Shops,
3.5 Mio Artikel. Alle Bestseller, Servertechnik und Technik Themenwelten.

Notebooks und Netzwerkhardware bei Mercateo günstig kaufen.
Internet Telefonie mit VoIP Telefonen von Gigaset
Das B2B Portal www.Linx.de informiert über Produkte und Dienstleistungen.
Günstige Digitalkameras finden Sie im Preisvergleich.

Gleichmacherei

The Answer Girl

Alles nur geklaut

Jetzt wollen wir viele Dateien bearbeiten, am besten alle, die im aktuellen Verzeichnis stehen. Sowas sollte doch auch schon vor uns jemand mal gemacht haben. Perl-Skripte gibt es auf dieser Welt und im WWW viele, das mit der verständlichen Dokumentation ist hingegen so eine Sache. Ein Lichtblick für Neu-Perlianer/innen ist Brigitte Jellineks "Perlwelt" [2], die in kleinen, gut überschaubaren Perl-Skripten praktisch relevante Aufgaben löst.

Hier finden wir unter Viele Webseiten ändern [3] ein Skript, das in allen HTML-Dateien im aktuellen Verzeichnis die Umlaut-Entities in echte ISO-Umlaute umwandelt (Abbildung 1) und mit

$^I = ".bak";

zuvor sogar immer eine Backup-Datei mit der Endung .bak anlegt.

Abbildung 1: Abschreiben von Bjellis Perlwelt

Dieses letzte Feature markieren wir zunächst einmal mit einem # am Zeilenanfang so, dass der Interpreter es nicht beachtet. Indem wir die Zeile auskommentieren, ergibt sich als netter Nebeneffekt, dass wir einstweilen noch gar keine Dateien schreiben, sondern das Ergebnis auf der Standardausgabe angezeigt bekommen. Zum Testen ohnehin viel besser!

In Perl beginnen einfache (skalare) Variablen immer mit einem Dollarzeichen, und eine so komische Variable wie $^I muss schlichtweg etwas Vordefiniertes sein. Tatsächlich erklärt man perlvar, dass damit das Inplace-Editing, also das Editieren der gerade bearbeiteten Datei ein- oder abgeschaltet wird.

Auch die nächste Zeile,

@ARGV = <*.html>;

sieht nach einer vordefinierten Variablen aus, wegen des vorangestellten @ ein Array, also ein ein- oder mehrdimensionales Wertefeld. @ARGV, der "Argumentvektor", ist eindimensional und enthält laut der perlvar-Manpage die Kommandozeilenargumente des Skripts. Wir sind also sehr gewitzt und definieren erst innerhalb des Programms, mit welchen Argumenten es eigentlich aufgerufen wird: natürlich mit allen, die auf .html enden.

Perl sorgt bereits von sich aus dafür, dass die Argumentdateien geöffnet werden und man über das Handle <> Zugang zu den darin enthaltenen Daten bekommt. Wir müssen den Inhalt also lediglich zeilenweise abgreifen, bis es keine Zeilen mehr gibt:

while( $zeile = <> ) { }

Ein klarer Fall für eine Schleife, die immer wieder durchlaufen wird, solange (while) die in runden Klammern stehende Bedingung stimmt. Ob wir die zur Zwischenspeicherung benötigte Variable $zeile wie in [3] vorab mit der my()-Funktion deklarieren oder sie erst da entstehen lassen, wo wir sie brauchen, spielt bei Perl keine Rolle. Erst im Zusammenhang mit objektorientierter Perl-Programmierung wird my() wirklich wichtig. Allerdings schadet es nicht, sich von vornherein daran zu gewöhnen. Wenn wir den Inhalt von $zeile innerhalb der geschweiften Klammern mit

print $zeile;

wieder ausgeben, sollte unser Skript einfach den Inhalt der .html-Dateien im aktuellen Verzeichnis Zeile für Zeile ausgeben. Testen wir das in einem Verzeichnis, das (nicht zuviele) HTML-Files enthält. Da cgks vermutlich nicht im Suchpfad liegt, geben wir den Pfad mit an (z. B. den Punkt als Abkürzung für das aktuelle Verzeichnis).

pjung@chekov:~/answergirl$ ./cgks
 bash: ./cgks: No such file or directory

Keine Datei, kein Verzeichnis dieses Namens? Da ist etwas faul. Wir haben wohl vergessen, uns selbst mit chmod u+x cgks Ausführbarkeitsrechte zuzugestehen.

Muster erkennen

Da uns das Skript brav die Dateiinhalte ausgibt, können wir nun die Links raussuchen. Perl kennt das schöne Konstrukt der "per Default zu bearbeitenden Daten", die sich in der Variablen $_ verstecken. Wenn man nach etwas sucht, braucht man gar nicht angeben, worin zu suchen ist, wenn man den Inhalt von $_ meint. Wir wollen den Inhalt von $zeile bearbeiten und legen ihn daher mit

$_ = $zeile;

im Default ab. Gibt es Links in dieser Zeile? Wenn ja, folgen die auf ein <A HREF= innerhalb von Gänsefüßchen ("). Den Schluss bildet ein >. (Um das Skript nicht unnötig zu verkomplizieren, gehen wir davon aus, dass keine Zeilenumbrüche in dieser Zeichenfolge enthalten sind.) Als regulärer Ausdruck sieht das so aus:

<A HREF=\"(.*)\">

Die Gänsefüßchen müssen wir mit dem Backslash escapen, da sie auch in Perl zum Begrenzen von Stringinhalten benutzt werden. In runden Klammern merken wir uns die Referenz (entweder eine URL oder eine lokale Dateiangabe), eine beliebig lange Folge beliebiger Zeichen, .* abgekürzt.

Leider haben reguläre Ausdrücke die dumme Angewohnheit, immer soviel wie möglich abdecken zu wollen. Wenn nach dem HREF mehrere "> auf der Zeile vorkommen, wird die obige Regexp bis zum letzten Vorkommen alles in den runden Klammern speichern. Diese Gier gewöhnen wir ihr ab, indem wir das in diesem Zusammenhang etwas schwer zu erklärende Ein- oder Keinmal-Zeichen ? hinter .* setzen:

<A HREF=\"(.*?)\">

Um im Inhalt von $_ danach zu suchen, nutzen wir den "match"-Operator m/Muster/, dem wir mit einem i-Flag am Ende gleich sagen, dass a href auch kleingeschrieben werden darf ("case-insensitive Suche"). Auch wollen wir alle auf der Zeile vorkommenden Links einsammeln und bemühen dazu das Flag g ("global"):

@dateien = m/<A HREF=\"(.*?)\">/gi;

Das, was jeweils in den runden Klammern landet, speichern wir in einer Array-Variablen namens @dateien und gehen sie Schritt für Schritt durch:

foreach $datei ( @dateien ){ }

Die jeweils aktuelle Referenz legen wir dazu in der Variablen $datei ab, die als "Laufvariable" der foreach-Schleife automatisch in $_ landet. Um nur dann etwas zu ändern, wenn es sich um eine Referenz auf eine lokale Datei handelt, prüfen wir, dass ihr Inhalt nicht mit einem Protokoll wie ftp oder http beginnt (andere Protokolle wie gopher können wir vernachlässigen):

if ( ! /(ftp|http):\/\//i ){ }

Das m vom Match-Operator darf weggelassen werden, und "ftp:// oder http://" lässt sich zu (ftphttp):// verkürzen. Dabei dient das Pipe-Zeichen als logisches Oder. Da die Schrägstriche bereits das Muster einrahmen, müssen wir sie escapen, und um nicht auf Groß- und Kleinschreibung zu achten, nutzen wir das i-Flag des Match-Operators. Zu guter Letzt sorgt das Ausrufezeichen dafür, dass die Bedingung gerade dann erfüllt ist, wenn das Muster nicht gefunden wird.

Einem Freund empfehlen    Druckansicht Bookmark and Share
Kommentare

Hits
Wertung: 0 Punkte (0 Stimmen)

Schlecht Gut

Infos zur Publikation

Infos zur Publikation

LinuxUser 06/2012

Aktuelle Ausgabe kaufen:

Heft bestellen Heft als PDF kaufen

LinuxUser erscheint monatlich und kostet in der Nomedia-Ausgabe EUR 5,50 und mit DVD EUR 8,50. Weitere Informationen zum Heft finden Sie auf der LinuxUser-Homepage.

Im LinuxUser-Probeabo erhalten Sie drei Ausgaben für 3 Euro. Das Jahresabo (ab EUR 56,10) können Sie im LNM-Shop bestellen.

Tipp der Woche

Adobe AIR
Adobe-AIR-Programme installieren und (manuell) starten
Tim Schürmann, 14.05.2012 13:09, 0 Kommentare

Es gibt sie noch: neue Anwendungen, die Adobes Integrated Runtime voraussetzen. Aktuellstes und vermutlich auch größtes Beispiel ist das Adventure Botanicula

Aktuelle Fragen

gibt es ein Kommandozeilen Tool, um ein X11-Fenster in ein Anderes einzubetten?
GoaSkin , 21.05.2012 16:44, 0 Antworten
Das XEmbed-Protokoll ist u.A. dazu gedacht, dass man eine X11-Anwendung in eine andere wie ein Wi...
Apache2, Options -Indexes geht nicht
no no, 12.05.2012 19:01, 8 Antworten
Habe in apache2.conf folgendes stehen: Options -Indexes ...
LInux auf Dell LS H500
Andreas Endresl, 09.05.2012 08:54, 2 Antworten
Habe einen alten Dell Latitude LS H500 nur mit ext. Floppy und CD es geht nur immer eines von den...
Datenwiederherstellung unter Ubuntu 12.04 mit "Simple Backup" nach Umzug von Linux Mint
Christian Lottmann, 07.05.2012 13:33, 0 Antworten
Vor dem Umzug auf Ubuntu 12.04 habe ich unter Linux MInt mit "Simple Backup" voll (15.4.2012) und...
DKMS für den propritären NVIDIA-Treiber
Commander Data, 26.04.2012 22:02, 2 Antworten
Hallo an die Gemeinde. Ich habe hier ein interessantes Stück openSuSE gefunden. http://forums.op...