2017-10-28 2 views
0

Okay, ich habe ein Programm, das im Grunde untersucht in einem übergebenen Verzeichnis, wenn alle Dateinamen mit einem Muster übereinstimmen Ich werde ein Verzeichnis und verschieben Sie diese bestimmte Datei und jede, die es passt (unabhängig von der Erweiterung) in das Verzeichnis. Wenn sie nicht übereinstimmen, sollte ich sie in das Verzeichnis PassedInDir/misc/ verschieben.Perl-Verzeichnis ist vorbei, wenn (! -d) Anweisung? [readdir Ergebnisse]

Ich habe eine Bedingung in beiden Fällen zu vermeiden, in einem beliebigen Verzeichnis übergeben (wie mein Programm ist nicht bereit, mit denen noch zu tun) so etwas wie if(! -d $fp).

Alles funktioniert gut, wenn ich es das erste Mal im Verzeichnis ausführen. Wenn ich es jedoch erneut auf demselben Verzeichnis (das jetzt nur Verzeichnisse enthalten sollte) ausführen, erhalte ich den Fehler Could not move file assignmentZ to destination DataB/misc at projectSorter.pl line 16.. AssignmentZ ist ein Verzeichnis, das im zweiten Fall irgendwie über die (!-d) hinausgeht.

#!/usr/bin/perl -w 
use File::Copy; 
if(@ARGV < 1){ 
    print "\nUsage: proj6.pl <directory>\n\n"; 
    exit; 
} 
die("\nDirectory $ARGV[0] does not exist\n\n") if(! -e $ARGV[0]); 
opendir(DIR, $ARGV[0]) or die("\nCould not open directory $ARGV[0]\n\n"); 
while(($fp = readdir(DIR))){ 
    if($fp =~ m/proj(.*)\./){ 
     (! -d "$ARGV[0]/assignment$1") && (mkdir "$ARGV[0]/assignment$1"); 
     move("$ARGV[0]/$fp" , "$ARGV[0]/assignment$1") or die("Could not move file $fp to destination $ARGV[0]/assignment$1"); 
    } 
    elsif(! -d $fp){ #gets past here!!! 
     (! -d "$ARGV[0]/misc") && (mkdir "$ARGV[0]/misc"); 
     move("$ARGV[0]/$fp" , "$ARGV[0]/misc") or die("Could not move file $fp to destination $ARGV[0]/misc"); 
    } 
} 

Es ist das einzige Verzeichnis, das es aus denen macht, die vorher gemacht wurden, indem ich mein Programm einmal ausführte. Ich bin neugierig, warum das passiert.

Antwort

3

$fp wie von readdir eingestellt ist relativ zum gescannten Verzeichnis. chdir in das gescannte Verzeichnis eingeben oder den Namen des gescannten Verzeichnisses dem -d Test voranstellen.

Sie verwenden "$ARGV[0]/$fp" als Argument zum Verschieben der Funktion.

perldoc -f readdir

readdir DIRHANDLE
Gibt den nächsten Verzeichniseintrag für ein Verzeichnis von "opendir" geöffnet. [...]
Wenn Sie planen, die Rückgabewerte aus einem "readdir" zu filetieren, sollten Sie das Verzeichnis in Frage stellen. Ansonsten, weil wir dort nicht "chdir" hatten, wäre es gewesen, die falsche Datei zu testen.

0

Einige Vorschläge.

‣ Verwenden Sie nicht die Option -w mit Perl. Einige Module schalten Warnungen aus, um ihre Arbeit zu erledigen, aber das Flag -w ist global. Damit werden Warnungen angezeigt, die ignoriert werden sollten.

‣ Immer diese zwei Zeilen am Anfang jedes Skripts.

use strict; 
use warnings; 

Diese werden eine Menge Fehler in Ihrem Code erfassen. Weitere Details finden Sie unter perldoc strict und perldoc warnings.

‣ Verwenden Sie glob() oder Find::Find anstelle von opendir/readdir/closedir.

‣ Verwenden Sie make_path() von File::Path anstelle von mkdir.

‣ Verwenden Sie eine if-Anweisung für die bedingte Ausführung anstelle von &&.

‣ Legen Sie leere Zeilen in Ihren Code, um das Lesen zu erleichtern.

File::Find und File::path sind Standardmodule, die mit Perl installiert werden. Eine Liste der Standardmodule finden Sie unter perldoc perlmodlib.

#!/usr/bin/perl 

# -------------------------------------- 
# pragmas 

use strict; 
use warnings; 

# -------------------------------------- 
# modules 
use File::Copy; 
use File::Path qw(make_path); 

# -------------------------------------- 
# main 

# make sure there is something to work on 
if(@ARGV < 1){ 
    print "\nUsage: proj6.pl <directory>\n\n"; 
    exit; 
} 

# arguments should be directories 
for my $src_dir (@ARGV){ 

    # validate the source directory 
    die("\n$src_dir does not exist\n\n")  if(! -e $src_dir); 
    die("\n$src_dir is not a directory\n\n") if(! -d $src_dir); 

    # move proj* files 
    for my $proj (glob("$src_dir/proj*")){ 

     # get the proj number 
     (my $number) = $proj =~ m/proj(.*)\./; 

     # get the destination directory 
     my $dst_dir = "$src_dir/assignment$number"; 

     # create the directory where it goes 
     if(! -d $dst_dir){ 
      make_path($dst_dir) or die "could not make path $dst_dir"; 
     } 

     # move the file 
     move($proj, $dst_dir) or die("could not move file $proj to destination $dst_dir"); 

    } # end of $proj files 

    # move other files 
    for my $file (grep { ! -d } glob("$src_dir/*")){ 

     # get the destination directory 
     my $dst_dir = "$src_dir/misc"; 

     # create the directory where it goes 
     if(! -d $dst_dir){ 
      make_path($dst_dir) or die "could not make path $dst_dir"; 
     } 

     # move the file 
     move($file, $dst_dir) or die("could not move file $file to destination $dst_dir"); 

    } # end other files 

} # end of src_dir 
Verwandte Themen