Zum Inhalt springen

[Perl] rekursiv durch Dateibaum


Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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? ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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]

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...