Die »gängige Vorgehensweise« bei der Erstellung eines Perl-Skriptes ist zunächst das Skript zu schreiben, es zu speichern, gegebenenfalls die Ausführungsrechte zu setzen um es dann letztlich ausführen zu können. Handelt es sich bei dem Skript nur um eine oder wenige Zeilen Code, lohnt im Prinzip der ganze Aufwand nicht. Einfache und bequemer wäre es, »die paar Zeilen« direkt auf der Kommandozeile einzugeben und auszuführen. Abhilfe schaffen hierbei die sogenannten Einzeiler.
Damit ein Skript auf der Kommandozeile ausgeführt werden kann, ist perl mit der Option -e aufzurufen.
$ perl -e 'print "Give a little bit\n"' Give a little bit $
Zu beachten ist hier weiterhin, dass das »eigentliche Skript« in einfachen Anführungszeichen steht.
Das Zeichen für Newline kann auch über die Option -l erzeugt werden:
$ perl -l -e 'print "Give a little bit"' Give a little bit $
Analog hierzu kann auch auf der Kommandozeile gerechnet werden,
$ perl -l -e 'print 450 * 2.32' 1044 $
oder die Ausgabe von (Unix-) Befehlen ausgewertet werden.
$ date | perl -n -e 'print "Heute ist $_"' Heute ist Mon May 3 12:31:21 CEST 2004 $
Um Dateien zeilenweise - ähnlich wie bei awk und sed - zu verarbeiten, ist perl mit der Option -n aufzurufen. So gibt beispielsweise der Aufruf
$ perl -n -e 'print' /etc/passwd
die Passwort-Datei zeilenweise aus. Die Option -n bewirkt im Grunde genommen nichts anderes als eine while-Schleife, innerhalb der die betreffende Datei zeilenweise abgearbeitet wird.
while (<>) {
....
}
Die Verarbeitung der einzelnen Zeilen kann an einzelne Bedingungen oder Kontrollstrukturen verknüpft werden, so dass nur bestimmte Angaben angezeigt werden. Der folgende Aufruf zeigt die Eintragungen der Passwort-Datei für den Anwender tl:
$ perl -n -e 'print $_ if /tl/' /etc/passwd tl:*:1000:100:Thomas Lingmann:/home/tl:/bin/bash $
Analog können auch Systemausgaben auf bestimmten Angaben reduziert werden, damit beispielsweise nur die installierten Perl-Module angezeigt werden.
$ pkg_info | perl -n -e 'print $_ if /^p5/' p5-Net-1.15 Perl5 modules to access and use network protocols p5-Date-Manip-5.42a Perl5 module for date calculations p5-Digest-MD5-2.33 Perl5 extension interface for MD5 algorithm ....
Vereinzelt ist es nicht erforderlich sich die gesamten Informationen einer Zeile anzeigen zu lassen, sondern nur einen bestimmten Teil davon. Um die Ausgabe aus dem vorigen Beispiel auf die Anzeige der installierten Pakete zu beschränken, ist bei dem Aufruf zusätzlich die Option -a anzugeben. Dadurch werden die jeweiligen Zeilen in einzelne »Elemente zerlegt«, wobei Leerzeichen als Trennungszeichen fungieren. Die so »zerlegten Elemente« werden in ein Array @F eingelesen, welches dann wiederum ausgelesen bzw. »anderweitig verarbeitet« werden kann.
$ pkg_info | perl -l -a -n -e 'print $F[0] if /^p5/' p5-Net-1.15 p5-Date-Manip-5.42a p5-Digest-MD5-2.33 ....
Anstatt des Leerzeichens als Trennungszeichen kann über die Option -F auch ein beliebig anderes angegeben werden. Auf diese Weise extrahiert beispielsweise der Aufruf
$ perl -l -a -n -F: -e \
'print "$F[2] \t $F[3] \t $F[0]"' /etc/passwd
die UID und GID sowie das Login aus der Passwort-Datei und gibt die Angaben aus. Eine weitere - etwas kürzere - Variante könnte so aussehen:
$ perl -l -a -n -F: -e \
'print(join("\t", @F[2,3,0]))' /etc/passwd
Prinzipiell könnte der Aufruf noch »kompakter« erfolgen, indem die einzelnen Optionen zusammengefasst werden.
$ perl -lanF: -e \
'print(join("\t", @F[2,3,0]))' /etc/passwd
Hier ist allerdings Vorsicht geboten. Das Zusammenfassen von Optionen kann zu Fehlinterpretationen bei der Ausführung kommen oder aber auch zum Abbruch des Programmes führen. So werden die beiden folgenden Aufrufe mit einer Fehlermeldung abgebrochen.
$ perl -lanF:e 'print(join("\t", @F[2,3,0]))' /etc/passwd
$ perl -laneF: 'print(join("\t", @F[2,3,0]))' /etc/passwd
Die Option -p bietet sich insbesondere bei Änderungen von Dateien an. Der wesentliche Unterschied zwischen den Optionen -n und -p liegt darin, dass -p die jeweils bearbeitete Zeile automatisch ausgibt. So kann beispielsweise der Urlaubs-Antrag in der Datei urlaub.txt
Hi Chef, aufgrund meines außerordentlichen Einsatzes in den letzten zwei Stunden, beantrage ich bezahlten Sonderurlaub für die nächsten zehn Tage.
mit folgendem Aufruf geändert werden.
$ perl -p -e 's/Tage/Wochen/' urlaub.txt Hi Chef, aufgrund meines außerordentlichen Einsatzes in den letzten zwei Stunden, beantrage ich bezahlten Sonderurlaub für die nächsten zehn Wochen. $
Der auf diese Weise geänderte Text wird auf der Standardausgabe ausgegeben. Mit der Option -i wird der Text direkt in der Datei geändert.
$ perl -p -i.bak -e 's/Tage/Wochen/' urlaub.txt
Mit diesem Aufruf wird zunächst die Originaldatei nach urlaub.txt.bak kopiert, bevor der Text in urlaub.txt geändert wird. Die »Kennung« der Originaldatei kann auch am Anfang des Namens erfolgen. Die Befehlsfolge
$ perl -p -i'orig_*' -e 's/Tage/Wochen/' urlaub.txt
legt das Original unter orig_urlaub.txt ab.
Beide Aufrufe können auch auf mehrere Dateien gleichzeitig angewandt werden. Um beispielsweise das Zeichen ß in allen HTML-Dateien im aktuellen Verzeichnis mit ß zu ersetzen, ist folgender Aufruf einzugeben
$ perl -p -i.bak -e 's/ß/ß/' *.html
Über die Option -M können einzelne Module in die Skriptausführung eingebunden werden. Die aktuelle Uhrzeit nebst Datum lässt sich - unter Verwendung des Moduls Date::Manip - wie folgt anzeigen:
$ perl -l -MDate::Manip -e \
'print UnixDate("today", "Heute ist der %d.%m.%Y")'
Heute ist der 03.05.2004
$
Falls Ihr Vorgesetzter Ihnen frühestens in 20 Arbeitstagen den » wohlverdienten Urlaub« genehmigen will, ist folgender Aufruf einzugeben:
$ perl -l -MDate::Manip -e \
'print UnixDate(DateCalc("today", "+ 20 business days"),
"Mein erster Urlaubstag ist am %d.%m.%Y")'
Mein erster Urlaubstag ist am 31.05.2004
$
Wie aus den Beispielen ersichtlich ist zur Einbindung eines Moduls lediglich dessen Name nach der Option -M (ohne Leerzeichen) anzugeben.
Ein weiteres, interessantes Modul ist in diesem Zusammenhang LWP::Simple. Das Modul gehört zu einer Sammlung von Modulen, die verschiedene Zugriffsmöglichkeiten auf das World Wide Web bieten. Die Bezeichnung Simple kommt nicht von ungefähr, wie der folgende Aufruf verdeutlicht:
$ perl -MLWP::Simple -e 'getprint("http://www.cul.de")'
Die Befehlsfolge holt den Inhalt von http://www.cul.de und gibt ihn auf der Standardausgabe aus. Soll die Seite dagegen nicht angezeigt, sondern in einer Datei lokal gespeichert werden, ist die Funktion getstore() aufzurufen.
$ perl -MLWP::Simple -e \
'getstore("http://www.cul.de", "cul.html")'
Mit diesem Aufruf wird die Seite im aktuellen Verzeichnis unter cul.html gespeichert.
Weitere, unter dem CPAN erhältliche Module können - sofern sie sich für einen »Einzeiler« eignen - auf die gleiche Art eingebunden werden.
Ausgabe aller Zeilen einer Datei mit vorangestellter - dreistelliger - Zeilennummer:
perl -p -e '$_ = sprintf( "%03d: %s", $., $_ )' <name_der_datei>
Ausgabe aller Zeilen einer Datei in umgekehrter Reihenfolge:
perl -e 'print reverse <>;' <name_der_datei>
Entfernt aus jeder Zeile einer Datei die führenden Leerzeichen:
perl -e 'while(<>){s/^\s+//g;print;}' <name_der_datei>
Ausgabe des Inhalts einer Datei in Großbuchstaben:
perl -e 'while(<>){print uc $_;}' <name_der_datei>
Ausgabe des Inhalts einer Datei in Kleinbuchstaben:
perl -e 'while(<>){print lc $_;}' <name_der_datei>
Alle Dateien im Verzeichnis /var/log/ ausgeben, die eine Fehlermeldung (Error) beinhalten:
perl -ne 'print "$ARGV\n" if /Error/i' /var/log/*
»Löschen« aller Zeilen einer Datei, welche die Zeichenfolge regex enthalten:
perl -l -a -n -e 'print unless m/regex/' <name_der_datei>
Entfernen der unter DOS üblichen Zeilentrenner einer Datei:
perl -i -p -e 's/\015//g;' <name_der_datei>
Zeilenumbruch nach 64 Zeichen durchführen:
perl -MText::Wrap -n -e \
'$Text::Wrap::columns=64; print wrap("","",$_)' <name_der_datei>
Prüfsumme (»MD5-Hashwert«) einer Zeichenfolge erstellen:
perl -MDigest::MD5 -l -e 'print Digest::MD5::md5_hex("zeichenfolge")'
Prüfsumme (»MD5-Hashwert«) einer Datei erstellen:
perl -MDigest::MD5 -l -e \
'open(FH, $ARGV[0]); \
binmode(FH); \
print Digest::MD5->new->addfile(*FH)->hexdigest' <name_der_datei>
Weitere Hinweise und Beispiele zur Nutzung von Perl auf der Kommandozeile finden sich im entsprechenden Manual, welches über das Kommando perldoc perlrun aufgerufen werden kann.