PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Subroutine für Ausgabe von mehreren Dateien



pebbles
19-10-2006, 22:36
Hallo,

ich muß in einer Subroutine mehrere Dateien einlesen können.
Der Inhalt jeder Datei soll jeweils in einer Datei abgelegt werden,
sprich umgeleitet werden.
Wie das für eine Datei funktioniert, weiß ich schon.
Wie funktioniert es aber für alle Dateien aus einem Verzeichnis?

Gruß,
pebbles

sticky bit
20-10-2006, 06:45
Stichworte:
opendir()
readdir()
closedir()

pebbles
20-10-2006, 17:51
Tja,
da habe ich wohl nicht die beste Ausdrucksweise gefunden.
Das kenne ich ja auch.:)
Es geht eher darum, daß ich mit "readdir" alle Dateien einlese,
und dann evtl. mit "open" jede Datei öffne,
um den Inhalt jeder Datei jeweils in eine andere Datei umzuleiten,
so daß ich bekomme: datei1, datei2 usw.

Danke,
pebbles

sticky bit
20-10-2006, 19:44
Hmm, jetzt versteh ich das Problem nicht mehr. Du weisst wie es geht, aber du hast ein Problem es so zu machen? Aber welches? Gibt es einen Fehler oder kommst du mit der Syntax nicht klar? Sorry, ich verstehs grad nicht...

pebbles
20-10-2006, 21:03
Also, alle Dateien aus einem Verzeichnis werden mit "readdir" eingelesen.
(d.h. Auflistung aller Dateien).
Dann will ich sagen, in einer while-Schleife soll jede Datei (z.B.: Datei a, Datei b, Datei c vom Verzeichnis A) zeilenweise eingelesen werden und in eine bestimmte Datei (z.B. Datei a_backup, Datei b_backup, Datei c_backup) ausgegeben werden.
In jeder neuen Ausgabedatei passiert irgendetwas mit den Originaldateien
und darum brauche ich eine Umleitung in neue Dateien.
Ich hoffe, jetzt ist es klar, was ich damit meine.

sticky bit
20-10-2006, 23:39
Hoffe ich habs jetzt kapiert es gehts ums "umleiten"?

Aber was ich dann schon wieder nicht verstehe, im ersten Post hast du geschrieben du wüssest wie du das für eine Datei machen musst. Warum packst du das nicht einfach in ne Schleife die über all die Dateien im Verzeichnis läuft? Oder wo ist da das Problem?

Poste doch vielleicht mal deinen Quelltext von deiner "Umleitung" und deiner Schleife und sag an welcher Stelle da jetzt was rein soll und was da jetzt aber nicht geht oder du nicht weisst wie es gehen könnte...

pebbles
21-10-2006, 11:34
Danke für die Antwort ! Hier folgt der Code:


use strict;
use warnings;

sub lese_inhalt_dateien {
my $some_dir = "C:\\Dokumente und Einstellungen\\user\\Eigene Dateien\\Dir";
my $file = "C:\\Dokumente und Einstellungen\\user\\Eigene Dateien\\Dir\\irgendwo.txt";

opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
my @directory = readdir(DIR);
foreach my $directory(@directory){
if($directory =~ /.txt/){
#print $directory,"\n";

open(FILE1, "<$directory") || die "Cannot do this:$!";
open(FILE2, ">$file") || die "Es geht nicht: $!";
while(my $zeile = <FILE1>) {
print $zeile;
}
}
}

}
lese_inhalt_dateien();

close FILE1;
close FILE2;
closedir DIR;

Momentan gebe ich den Inhalt aller Dateien in das DOS-Fenster aus.
Ich wollte aber den ganzen Inhalt in $file "umleiten" oder wenn es gehen würde, in mehrere separate Dateien. Da weiß ich nicht so genau,
wie die Syntax aussehen sollte.

sticky bit
21-10-2006, 12:36
OK, ich glaube ich verstehe. Du möchtest wissen, dass man u. A. mit print($filehandle $text) den Inhalt von $text in eine Datei schreiben kann wenn $filehandle ein gültiger, beschreibbarer Filehandle ist? (Es ist kein Tippfehler, dass da kein Komma steht, das gehört so!)

Um das ganze in mehrere Datein zu machen müsstest du halt einfach für jede Datei die du einliesst eine andere neue aufmachen, z. B. in dem du an den Dateinamen der alten Datei einfach ein Suffix anhängst...

Übrigens solltest du in deiner Subroutine die Dateien auch wieder schliessen, da du, wenn du diese wieder verwenden willst in einem anderen Programm du evtl. nicht mehr weisst, dass diese offene Filehandles hinterlässt und dann lauter Schrott rum liegen lässt. Es ist keine gute Idee Subroutinen zu schreiben die die Umgebung nach dem verlassen in so einer weise verändern sofern dies nicht ausdrücklich der Zweck dieser Routine ist! Das Schliessen sollte in dem Fall am besten in der Schleife passieren, und zwar dann wenn es nichts mehr zu lesen oder zu schreiben gibt, so früh wie möglich also!

Also in etwa so (Änderungen hab ich fett markiert; Getestet hab ichs nicht geht nur ums Prinzip):


use strict;
use warnings;

sub lese_inhalt_dateien {
my $some_dir = "C:\\Dokumente und Einstellungen\\user\\Eigene Dateien\\Dir";
my $suffix = ".bakup";

opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
my @directory = readdir(DIR);
foreach my $directory(@directory){
if($directory =~ /.txt/){
#print $directory,"\n";

open(FILE1, "<$directory") || die "Cannot do this:$!";
open(FILE2, ">$directory.$suffix") || die "Es geht nicht: $!";
while(my $zeile = <FILE1>) {
print(FILE2 $zeile);
}
}
close(FILE1) || die("Jetzt geht gar nichts mehr... $!");
close(FILE2) || die("Jetzt geht gar nichts mehr... $!");
}
closedir(DIR) || die("Alles kaputt... $!");
}

lese_inhalt_dateien();


Ausserdem solltes du vielleicht die Subroutine so schreiben, dass du das Verzeichnis und vielleicht auch das Suffix übergeben musst, dann kannst du das auf beliebige Verzeichnisse anwenden. Die Argumente an eine Subroutine sind in dieser im Array @_ verfügbar, Reihenfolge der Elemente ist wie übergeben...

Und zusätzlch solltest du noch prüfen was der Verzeichnis-Eintrag den du gerade liesst gerade ist, um die nachfolgenen Operationen z. B. nicht auf einem Verzeichnis auszuführen, das in dem Verzeichnis liegt (das geht nämlich schief), nicht lesbare Dateien etvl. auszulassen, etc....
Stichwort dazu sind Dateitestoperatoren, einfach mal danach suchen...

pebbles
21-10-2006, 14:52
Hi,
Vielen Dank für die ausführlichen Erklärungen !
Ich habe den Skript mit Deinen Änderungen getestet
und da kam zuerst...eine Fehlermeldung wegen der beiden close - Befehle
von den Files und zwar:


Jetzt geht gar nichts mehr: Bad file descriptor at lese_alle_dirs_neu.pl line 23.

Danach habe ich sie erst nach dem Schliessen der foreach-Schleife eingefügt und der Skript hat einwandfrei funktioniert.
Natürlich wäre eine Subroutine für beliebige Verzeichnisse und Dateien noch besser.
An Dateitestoperatoren habe ich in diesem Fall gar nicht gedacht,
daß sie mir helfen könnten, danke für den Tipp!

sticky bit
21-10-2006, 17:59
use strict;
use warnings;

sub lese_inhalt_dateien {
my $some_dir = "C:\\Dokumente und Einstellungen\\user\\Eigene Dateien\\Dir";
my $suffix = ".bakup";

opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
my @directory = readdir(DIR);
foreach my $directory(@directory){
if($directory =~ /.txt/){
#print $directory,"\n";

open(FILE1, "<$directory") || die "Cannot do this:$!";
open(FILE2, ">$directory.$suffix") || die "Es geht nicht: $!";
while(my $zeile = <FILE1>) {
print(FILE2 $zeile);
}
close(FILE1) || die("Jetzt geht gar nichts mehr... $!");
close(FILE2) || die("Jetzt geht gar nichts mehr... $!");
}
}
closedir(DIR) || die("Alles kaputt... $!");
}

lese_inhalt_dateien();


Hab's aus Versehen ausserhalb des ifs eingefügt, so sollts gehen...