2017-09-03 1 views
0

ich Probleme habe meine Perl-Skript bekommen einige Unterverzeichnisse zu erkennen, wenn durch mein Dateisystem durchlaufen.Perl-Skript erkennt nicht alle Verzeichnisse mit -d Flag

Bitte beachten Sie, dass dies Teil einer Hausaufgabe ist, und ich bin nicht in der Lage Module jeglicher Art zu verwenden. Ich habe versucht, dieses Problem für einige Zeit selbst zu beheben, und bin jetzt an einer Straßensperre.

Ich bin versucht, eine Dateistruktur, erfassen die Namen aller Dateien, Verzeichnisse zu durchqueren, und Verzeichnisse in ihre jeweiligen Arrays und sie in dem dargestellten Format unten ausdrucken:

Directory: ./ 
Files: file1.text file2.pl file3.text 
Directories: subdir1 subdir2 subdir3 

Directory: subdir1 
Files: file3.text file4.pl 
Directories: subdir42 

.. .und so weiter.

Ich habe versucht, Rekursion als Lösung dieses Problems zu verwenden, aber mein Lehrer darauf hingewiesen, dass die Rekursion nicht der geeignete Weg war, dieses Problem zu behandeln.

Ich habe drucken verwaltet werden, im entsprechenden Format, das aktuelle Arbeitsverzeichnis und Unterverzeichnisse im aktuellen Arbeitsverzeichnis.

Aus irgendeinem Grund, wenn ich den aktuellen Codeblock zu

if (-d $entry){ 
     next if $entry =~/^\./; 
     push(@subdirs,"$entry"); 
     push(@dirs,"$currdir/$entry"); 
     } 

     elsif(-f $entry) { 
     push(@files,"$entry"); 
     } 

Es einige der Unterverzeichnisse werden weglassen ändern.

finden Sie das gesamte Skript unten.

#!/usr/bin/perl 
use strict; 
use warnings; 


sub traverse { 

my @dirs = ('.'); 
my @subdirs; 
my @files; 
    while(my $currdir = shift @dirs){ 

    opendir(my $dirhandle, $currdir) or die $!; 

     while(my $entry = readdir $dirhandle){ 

     if (-d -r $entry){ 
     next if $entry =~/^\./; 
     push(@subdirs,"$entry"); 
     push(@dirs,"$entry"); 
     } 

     else { 
     push(@files,"$entry"); 
     } 

    } 
     print "Directory: $currdir\n"; 
     print "Directories: "; 
     print "@subdirs"; 
     print"\n"; 


     print "Files: "; 
     foreach my $curfile (@files) { 
      next if $curfile eq '.' or $curfile eq '..'; 

      if ($curfile =~ /(\S*\.delete)/){ 
        unlink "$currdir/$curfile"; 
      } 

      $curfile =~ s/txt$/text/; 
      print "$curfile "; 
     } 

    print "\n"; 
    close $dirhandle; 
    undef @files; 
    undef @subdirs; 

} 
return; 
} 
traverse(); 

Und die aktuelle Ausgabe:

Directory: . 
Directories: test dir_3 test2 
Files: recursion.text count_files.pl testing.text thelastone.pl testing.pl prog5_test.pl program51.pl program5.pl recursion.pl recurse.text prog52.pl 
dirs.pl 

Directory: test 
Directories: 
Files: testfile1.text prog5_test.pl stilltesting program5.pl testfile2.text dirs.pl 

Directory: dir_3 
Directories: 
Files: 

Directory: test2 
Directories: 
Files: file2.text moretesting file3.text 

stilltesting und moretesting sollte als Verzeichnisse erkannt werden.

+1

Du bist gerade '-r' - wenn es nicht, es ist eine Datei? Das scheint komische Logik - Sie sollten überprüfen, ob es ein Verzeichnis oder eine Datei ist - ob es lesbar ist, ist eine andere Frage, die eine separate Behandlung verdient. – bytepusher

+0

Sie sollten Ihren Code sorgfältiger gestalten: Ihr Einzug ist überall. Außerdem sollten Sie die Anführungszeichen aus "$ entry" entfernen, da sie unnötig sind und in einigen Fällen Probleme verursachen können. – Borodin

+1

Danke @Borodin, du hast absolut recht. Ich habe das Skript nach deinem Vorschlag modifiziert. –

Antwort

0
if (-d $entry) 

sollte

sein
if (-d "$currdir/$entry") 

$entry ist nur ein Name in einem Verzeichnis. -d benötigt einen tatsächlichen Pfad.

+0

Bedeutung '-d -r $ entry' sollte '-d $ entry' sein sollte' -d "$ currdir/$ entry" '. Ich hatte gehofft, er würde dies sehen, nachdem er einen separaten '-r $ -Eintrag gemacht hat (als Warnung oder Ausnahme). Ich war mir bezüglich der Hausaufgabenpolitik nicht ganz sicher, um ehrlich zu sein. – bytepusher

+0

Danke @melpomene, genau das habe ich vermisst. Das Skript funktioniert nun wie vorgesehen. –

+0

@bytepusher, '-d -r" $ currdir/$ entry "' ist völlig in Ordnung. Seit 5.10 bedeutet es "-d" $ currdir/$ entry "&& -r" $ currdir/$ entry "' – ikegami

Verwandte Themen