Skyler99 has asked for the wisdom of the Perl Monks concerning the following question:

Monks, I need help trying to copy and rename a file in the destination directory. I don't have any errors however I cannot tell where the program fails due to my inexperience with copying and renaming files. Could you look at my code and let me know what do I need to change to make it work.
#! perl -w use strict; use File::Copy; my $infile = "c:/doclisth.chr"; open IN, "<$infile" or die "Couldn't open $infile, $!"; while (<IN>) { chomp; my @fields = split /,/; my $newfile = $fields[0]; my $path_str = $fields[13]; do { warn "Empty field 14"; next } unless $path_str; my @path = split /\\/, $path_str; my $dir = join "\\", @path[ 0, 5, 6 ]; process_dir($dir,$newfile); } close IN; sub process_dir { my $dir = shift; do { warn "$dir does not exist!\n"; return } unless -e $dir; opendir DIR, $dir or do { warn "Could not open $dir $!\n" ; return }; while ( my $file = readdir DIR ) { next unless -f "$dir\\$file"; next unless $file =~ m/\.rtf$/; copy( "$dir\\$file", "C:\\testfiles\\$file" ) or die "Failed to copy $file: $!\n"; rename $file, $newfile or die "Can't rename '$file' to '$newfile': $!\n"; } }

Replies are listed 'Best First'.
Re: Copy and Rename file at destination directory
by pzbagel (Chaplain) on Jun 04, 2003 at 04:31 UTC

    You never set $newfile in sub process_dir. You pass it in but never shift it off @_. Which is poor form even though it seems to work. Other than that, nothing jumps out at me. Since you get no errors, one would tend to thing that those next unless lines are triggering on all entries in the directory. Sprinkle in several print statements and see whether your script even gets to the copy or rename statements. I usually like to print out the inputs of test conditions before doing tests so I can see whether it should have triggered or not.

    print "dir: $dir file:$file newfile:$newfile\n"; #before the next unless statements.

    HTH

    HTH

      PZbagel should I do "my $newfile = shift; or how could I pass it to the structure??

        Exactly, now try the print statement debugging idea and let us know what you find.

Re: Copy and Rename file at destination directory
by Skeeve (Parson) on Jun 04, 2003 at 05:36 UTC
    instead of
    copy( "$dir\\$file", "C:\\testfiles\\$file" ) or die "Failed to copy $file: $!\n"; rename $file, $newfile
    You should try:
    copy( "$dir\\$file", "C:\\testfiles\\$file" ) or die "Failed to copy $file: $!\n"; rename "C:\\testfiles\\$file", "C:\\testfiles\\$newfile";
    But have you ever tried this:
    copy( "$dir\\$file", "C:\\testfiles\\$newfile" ) or die "Failed to copy $file: $!\n";
    Question: What will happen if you copy more than one file from $dir?

    Answer: You will end up with just one $newfile.

    Then regarding your not-shifted $newfile parameter to your sub. Instead of shifting a sub's parameters I prefer to write:

    sub process_dir { my ($dir, $newfile) = @_;
      Dear Monk I try to compiled the code but it gave me an error. I put a print statement before the next statements so I could get an accurate result on what the script is doing. This is the error :
      dir: C:\Apps\Impac\Db\Escribe\07\00002A0F.002 file: newfile:270917 dir: C:\Apps\Impac\Db\Escribe\07\00002A0F.002 file:STATUS.TXT newfile: +270917 dir: C:\Apps\Impac\Db\Escribe\07\00002A0F.002 file:WORD1.RTF newfile:2 +70917 Failed to copy Word1.rtf: No such file or directory
      I'm trying to copy the RTF file and not the TEXT . I cannot tell if the script is getting mix up with trying to rename the RTF and TEXT. Could you take a look at the code and let me know if I need to change anything to make it work. Thanks in advance
      #! perl -w use strict; use File::Copy; my $infile = "c:/zip files misc/doclisth.chr"; open IN, "<$infile" or die "Couldn't open $infile, $!"; while (<IN>) { chomp; my @fields = split /,/; my $newfile = $fields[0]; my $path_str = $fields[13]; do { warn "Empty field 14"; next } unless $path_str; my @path = split /\\/, $path_str; my $dir = join "\\", @path[ 0, 1, 2, 3, 4, 5, 6 ]; process_dir($dir,$newfile); } close IN; sub process_dir { my ($dir, $newfile) = @_; do { warn "$dir does not exist!\n"; return } unless -e $dir; opendir DIR, $dir or do { warn "Could not open $dir $!\n" ; return }; while ( my $file = readdir DIR ) { print "dir: $dir file:$file newfile:$newfile\n"; #before the next unless statements. next unless -f "$dir\\$file"; next unless $file =~ m/\.rtf$/; copy( "$dir\\$file", "C:\\testfiles\\$newfile" ) or die "Failed to copy $file: $!\n"; } }
        If I might make a suggestion, try stripping everything down so that you are just running the copy() and explicitly give it path/filenames. Then work backwards from there.

        "Ex libris un peut de tout"