kingofbrain Geschrieben 3. April 2005 Teilen Geschrieben 3. April 2005 Hallo zusammen, ich mache gerade meine ersten Schritte mit Perl und möchte ein kleines Skript, mit dem ich rekursiv durch einen Dateibaum gehe und dort gefundene Ordner und Dateien ausgebe. Das mache ich mit folgendem Skript #!/usr/local/bin/perl # # recursively walk through a filetree # list_files("/home/goetzp"); sub list_files { opendir(DIR, @_[0]); while($file = readdir(DIR)) { if($file ne "." && $file ne "..") { $file = @_[0] . "/" . $file; # file is a directory if(-d $file) { print $file . "\n"; list_files($file); } else { print $file . "\n"; } } } closedir(DIR); } [/PHP] Leider läuft das Skript nur bis zum ersten Verzeichnis. Kann mir einer von Euch den Fehler nennen, ich denke, es müsste ein Anfängerfehler sein. Ich habe versucht, die Variablen mit my oder local zu initialisieren. Das hat zwar einen Effekt, aber nicht den gewünschten. Kann aber auch sein, dass ich das Prinzip noch nicht umrissen habe. Vielen Dank für Eure Hilfe! Peter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
mtn Geschrieben 3. April 2005 Teilen Geschrieben 3. April 2005 Dein @_[0] was wohl der erste Wert eines Arrays sein soll, den du deiner Sub übergibst (und den ich eher $_[0] benennen würde, wenn ich das so richtig interpretiere) opendir(DIR, @_[0]); ist imho in der while-Schleife while($file = readdir(DIR)) { if($file ne "." && $file ne "..") { $file = @_[0] . "/" . $file; # file is a directory if(-d $file) { print $file . "\n"; list_files($file); } else { print $file . "\n"; } } } nicht mehr gültig, da in der while-Schleife @_, $_ und andere Systemvariablen jeweils neu gesetzt werden, sie gelten also immer nur im Bereich des jeweiligen Blocks. Grüße Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
kingofbrain Geschrieben 4. April 2005 Autor Teilen Geschrieben 4. April 2005 Guten Morgen mtn, vielen Dank für die Antwort! Das @ habe ich deshalb genommen, weil es in dem Tutorial, das ich verwende, heisst, dass das @ für Arrayvariablen steht und das @_ für das Array der übergebenen Parameter steht. Aber ich werde das heute abend mal ausprobieren. Vielen Dank schon mal! [Edit] So, ich habe es jetzt mal schnell hier auf dem Arbeitsrechner ausprobiert. Das Zuweisen des ersten Parameters an eine Variable hat nichts gebracht. Ich habe aber jetzt gesehen, dass das Skript scheinbar abbricht, wenn es aus der ersten Rekursion wieder zurückkommt. Also folgender Dateibaum: /home/pgoetz /home/pgoetz/.file1 /home/pgoetz/.file2 /home/pgoetz/dir1/ /home/pgoetz/dir1/file1 /home/pgoetz/dir1/file2 /home/pgoetz/dir2/file1 /home/pgoetz/dir2/file2 Er gibt richtigerweise die files file1 und file2 in pgoetz aus und geht in der Rekursion in dir1. Dort gibt er auch file1 und file2 korrekt aus. Danach sollte er ja eigentlich zurück zu pgoetz gehen und dort mit dir2 fortfahren. Das passiert aber nicht. Hat jemand einen Tipp für mich, wieso die Rekursion beim zurückkommen nicht korrekt fortfährt? [/Edit] Peter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SNOWMAN Geschrieben 4. April 2005 Teilen Geschrieben 4. April 2005 Hallo zusammen, #!/usr/local/bin/perl # # recursively walk through a filetree # list_files("/home/goetzp"); sub list_files { opendir(DIR, @_[0]); while($file = readdir(DIR)) { if($file ne "." && $file ne "..") { $file = @_[0] . "/" . $file; # file is a directory if(-d $file) { print $file . "\n"; list_files($file); } else { print $file . "\n"; } } } closedir(DIR); } [/PHP] Das is n einfacher Fehler! ok, also du hast als startordner /home/goetzp dann ließt du alle "Dinger" da drin aus und gibst die aus mit @_[0]."/".$file z.b. /home/goetzp/index.html ist $file aber ein Ordner so rufst du die Funktion mit $file auf, also mit www jetzt will er den Ordner /www öffnen, den gibts aber nicht, aber es gibt /home/goetzp/www. Du siehst den Fehler? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
kingofbrain Geschrieben 4. April 2005 Autor Teilen Geschrieben 4. April 2005 Servus SNOWMAN, ich weise doch der Variable $file den Wert des Directories plus den Filenamen zu, oder? Die Anweisung $file = @_[0] . "/" . $file; sollte das tun und ich denke, das klappt auch, weil die erste Rekursionsstufe funktioniert. Nur beim zurückkommen aus der sub wird der nächste Ordner nicht gefunden. Kann es sein, dass das Filehandle DIR nicht mehr gültig ist, wenn die Funktion zurückkehrt? Und wenn, wie bekomme ich die gültig? Peter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
SNOWMAN Geschrieben 4. April 2005 Teilen Geschrieben 4. April 2005 Uwaaa *anshirnklatsch* ich sollte so früh nich denken... ok, sorry, hast recht, der pfad stimmt natürlich. aber du hast auch damit recht das DIR nicht mehr gilt. immerhin - Du machst DIR auf - Du ließt alles ein - Findest ien Ordner - Machst DIR mit dem neuen Ordner auf - Ließt den ein - Machst DIR zu - Gehst zurück und versuchst DIR zu lesen du solltest dir vielleicht ne Variable $rootdir machen in der immer das übergeordnete Verzeichnis steht und das dann nach dem aufruf setzen bin mir nich ganz sicher damit, aber vllt. gehts so: sub list_files { opendir(DIR, @_[0]); while($file = readdir(DIR)) { if($file ne "." && $file ne "..") { $rootdir = @_[0]; $file = @_[0] . "/" . $file; # file is a directory if(-d $file) { print $file . "\n"; list_files($file); opendir(DIR, $rootdir); } else { print $file . "\n"; } } } closedir(DIR); } [/php] Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
kingofbrain Geschrieben 5. April 2005 Autor Teilen Geschrieben 5. April 2005 Servus zusammen, ich habe jetzt SNOWMANs letzten Tipp noch nicht umgesetzt, da ich im Web eine einfach zu benutzende Möglichkeit gefunden habe: use File::Find; find(\&<funktionsname>, <startverzeichnis>); sub funktionsname { # hier passiert was mit jeder Datei, z.B. print File::Find::name } Ich werde aber demnächst mal die andere Lösung noch umsetzen (zumindest versuche ich es, da mich das schon noch interessiert. Danke an alle! Peter Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.