Werbung einblenden Werbung ausblenden


Home / Tutorials / Perl Handbuch / Arbeiten mit Textdateien

eine Textdatei einrichten
a.) eine Textdatei anfügen
b.) eine Textdatei überschreiben / neu schreiben
c.) eine Textdatei lesen
den default Wert für den diamond operator ändern
Was haben wir gelernt?

eine Textdatei einrichten

Textdateien kann man in der Regel nur anlegen, lesen, schreiben und überschreiben. Man kann sie aber nicht direkt ändern. Einziger Ausweg ist dann die Anwendung einer relationalen Datenbank, siehe Zugriff auf relationale Datenbanken mit dem dbi Modul. Für Counter, Shops, Authentifizierungskripte, Foren etc. ist eine Flatfile Datenbank unter Umständen jedoch ausreichend.
Ein Beispiel zeigt, wie eine solche Textdatei eingerichtet wird. Mit ein bisschen rumprogrammieren kann auch eine komplette "Datenbank" Anwendungen mit Textdateien geschrieben werden. Das setzt allerdings voraus, dass die Textdatei eine Struktur hat. Strukturierter Text, der sich dann Datenbank ähnlich manipulieren lässt, nennt man Flatfile.

eine Textdatei anfügen

Wie eine Textdatei eingerichtet und angefügt wird, zeigt das folgende Beispiel:

$banane="Wenn die Sehnsucht vergeht, bleibt die Sehnsucht nach der Sehnsucht";
open(KIRSCHE,">>c:/nietzsche.txt");
print KIRSCHE  $banane;
close(KIRSCHE);

Wird dieses Skript ausgeführt, dann wird im Laufwerk C eine Datei mit dem Namen nietzsche.txt eingerichtet.
In diese Datei wird dann geschrieben "Wenn die Sehnsucht vergeht, bleibt die Sehnsucht nach der Sehnsucht".
Wie dies funktioniert, ist schnell erklärt:
Mit der Funktion open wird ein filehandle geöffnet, in diesem Fall KIRSCHE. Es ist günstiger, den filehandle mit Großbuchstaben zu schreiben, weil sonst beim Aufruf des Skriptes mit der Option -w die Meldung kommt: " kirsche may clash with future reserved words". Da aber nicht davon auszugehen ist, dass kirsche in Zukunft ein reserviertes Wort ist, kann es hier auch klein geschrieben werden.
KIRSCHE ist also ein Filehandle. Alle Operationen mit der Datei, z.B. drucken (print) gehen dann über den Filehandle, oder abstrakter formuliert, der STDOUT wird geändert. Zum Abschluss sollte der Filehandle wieder geschlossen werden.
Wird die Datei mit >> geöffnet, heißt das, Inhalte werden angefügt. Lässt man das Skript mehrere Male laufen, bekommt man eben mehrere Male: wenn die Sehnsucht vergeht bleibt die Sehnsucht nach der Sehnsucht.

eine Textdatei überschreiben / neu schreiben

Das ändert sich im folgenden Beispiel:

$banane="Wenn die Sehnsucht vergeht, bleibt die Sehnsucht nach der Sehnsucht";
open(KIRSCHE,">c:/nietzsche.txt");
print KIRSCHE  $banane;
close(KIRSCHE);

Wird die Datei mit > geöffnet, dann wird die Datei jedes mal neu geschrieben.
Das heißt, der alte Inhalt wird gelöscht, der neue reingeschrieben. Wenn man dieses Skript auslöst, ist folglich nietzsche.txt erstmal gelöscht und wird anschließend neu beschrieben. Egal wie oft das Skript ausgeführt wird, der Aphorismus (Wenn die Sehnsucht....) ist nur einmal vorhanden.

eine Textdatei lesen

Wie wird eine Textdatei ausgelesen?

open(KIRSCHE,"c:/nietzsche.txt");
@banane=<KIRSCHE>;
close(KIRSCHE);
print @banane[0];

Das Ergebnis von print @banane[0]; ist: "Wenn die Sehnsucht vergeht, bleibt die Sehnsucht nach der Sehnsucht" Schauen wir uns die entscheidende Zeile an:

@banane=<KIRSCHE>;

<> ist der sogenannte diamond operator. Der diamond operator (<>) in Verbindung mit dem file handle (KIRSCHE) ist der Inhalt der Datei.
Die ganze Zeile verschiebt den Inhalt der Datei nach @banane und zwar so, dass jede Zeile des Textes zu einem Element des Arrays wird.

Wir erstellen jetzt einen File vom_winde_verweht.txt im auf Laufwerk c. Dieser soll folgendes Aussehen haben.

Andres Ehmann
José Maria Aznar
Felipe Gonzales
Charles de Gaulle
Louis Bonaparte

Das folgende Programm generiert zuerst die Datei vom_winde_verweht.txt, dann werden die Werte reingeschrieben. Im letzten Schritt wird die ganze Datei ausgelesen:

@banane=("Andrés Ehmann \n","José Maria Aznar \n","Felipe Gonzales \n",
"Charles de Gaulle \n","Louis Bonaparte \n");
open(KIRSCHE,">c:/vom_winde_verweht.txt");
print KIRSCHE @banane;
close(KIRSCHE);

open(KIRSCHE,"c:/vom_winde_verweht.txt");
@pampelmuse=<KIRSCHE>;
close(KIRSCHE);

foreach $i(0..$#pampelmuse)
{
print " Hallo $pampelmuse[$i]";
}

Dieses Skript setzt dann nacheinander $pampelmuse[0] => Andres Ehmann, $pampelmuse[1] => José Maria Aznar, $pampelmuse[2]=>Felipe Gonzales etc. auf den Schirm.
Hinsichtlich der foreach Schleife und $#pampelmuse siehe Funktionen zur Bearbeitung von Arrays.
Das Skript funktioniert nur, wenn jeder Eintrag in einer Zeile steht. Das bedeutet, jede Zeile muss mit einem newline Zeichen \n enden. Dieses \n brauchen wir, um die Daten strukturiert auszulesen. \n muss anschließend mit dem chomp Befehl wieder entfernt werden.

Das Einlesen des Inhalts einer Datei mit dem diamond operator und dann Übergabe an einen Array (@banane=<KIRSCHE>) gilt als langsam. Wie es schneller geht, zeigt das folgende Beispiel:

@banane=("Andrés Ehmann \n","José Maria Aznar \n","Felipe Gonzales \n",
"Charles de Gaulle \n","Louis Bonaparte \n");
open(KIRSCHE,">c:/vom_winde_verweht.txt");
print KIRSCHE @banane;
close(KIRSCHE);

open(KIRSCHE,"c:/vom_winde_verweht.txt");
while (<KIRSCHE>)
{
chomp;
print " Hallo $_ \n";
}
close(KIRSCHE);

Erstens sehen wir, dass die chomp Funktion im Default auf $_ geht.
Zweitens, dass das Ergebnis des diamond operators in der Sondervariablen $_ gespeichert wird,
aus der es dann wieder ausgelesen werden kann.

den default Wert für den diamond operator ändern

Es kommt ziemlich selten vor, dass das newline Zeichen, an dem der diamond Operator <> ansetzt, um die Datei einzulesen, nicht verwendet werden kann. Trotzdem ist dieser Fall vorstellbar. Zum Beispiel könnte man auch so etwas haben.

zeile Andres Ehmann zeile Maria Martínez zeile Werner
Binsengrün zeile Heinrich Mann zeile Gottfried Keller zeile
Ernst Weiss zeile Robert Musil

Ein Datensatz steht zwischen zeile und zeile. Sollen die Datensätze nun eingelesen werden, wird es schwierig, weil an zeile aufgebrochen werden soll und nicht an \n, was für den diamond operator der Default ist. In diesem Zusammenhang kann auch ein anderes Zeichen definiert werden: Das sieht dann so aus:

@banane=("Andrés Ehmann zeile","José Maria Aznar zeile ","Felipe Gonzales zeile ",
"Charles de Gaulle zeile ","\n","Louis Bonaparte zeile ","\n","Thomas Mann zeile");
open(KIRSCHE,">c:/vom_winde_verweht.txt");
print KIRSCHE @banane;
close(KIRSCHE);
$/ = "zeile";
open(KIRSCHE,"c:/vom_winde_verweht.txt");
@pampelmuse=<KIRSCHE>;
close(KIRSCHE);

foreach $i(0..$#pampelmuse)
{
chomp($pampelmuse[$i]);
print " Hallo $pampelmuse[$i] \n";
}

Mit $/="zeile" haben wir den default Wert für den diamond operator geändert. Ein Element des Arrays ist folglich das, was nach zeile kommt. $/ ändert nicht nur den default Wert für den diamond operator <> sondern auch für chomp. Also chomp eliminiert jetzt das Wort zeile. Das Ändern von \n auf einen anderen Wert macht dann Sinn, wenn die Datensätze, die inhaltlich zusammengehören, sich über mehrere Zeilen erstrecken.

Was haben wir gelernt

open(KIRSCHE,">>c:/nietzsche.txt"); öffnet den file handle zum Anfügen.
open(KIRSCHE,">c:/nietzsche.txt");   öffnet den file handle zum Überschreiben / neu Schreiben.
open(KIRSCHE,"c:/nietzsche.txt");     öffnet den file handle zum Lesen.

Der diamond operator (<>) in Verbindung mit dem file handle ist der Inhalt der Datei.

vorhergehendes Kapitel