in reply to Re: Re: copy files
in thread Global symbol $dir requires a explicit package name ?

First please learn the value of indenting you code properly so you can see the flow. If you don't know how get a copy of perltidy from sourceforge and let it do it for you till it comes naturally. Try something like this:

#! perl -w use strict; use File::Copy; my $infile = "c:\\doclist1.chr"; my @directories; # first lets build our directory list open IN, "<$infile" or die "Couldn't open $infile, $!"; while (<IN>) { chomp; my @fields = split /,/; my $path_str = $fields[6]; do { warn "Empty field 7"; next } unless $path_str; my @path = split /\\/, $path_str; # push the directories into an array push @directories, join "\\", @path[ 0, 5, 6 ]; } close IN; # now we have a directory list in @directories let's process it for my $dir ( @directories ) { process_dir($dir); } exit; 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"; } }

Once you have the basic logic working you can add in File::Find if you need to recurse a directory structure in your process dirs sub. There were a lot of problems with your code. Foremost was that you wanted to push a list of directories into @directory but were not pushing and even if you were the my declaration in the loop would erase it every loop.

You actually don't need @directories at all a you can just call process_dirs() in your main loop like this:

#! perl -w use strict; use File::Copy; my $infile = "c:\\doclist1.chr"; open IN, "<$infile" or die "Couldn't open $infile, $!"; while (<IN>) { chomp; my @fields = split /,/; my $path_str = $fields[6]; do { warn "Empty field 7"; next } unless $path_str; my @path = split /\\/, $path_str; my $dir = join "\\", @path[ 0, 5, 6 ]; process_dir($dir); } 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"; } }

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Replies are listed 'Best First'.
Re: Re: Re: Re: copy files
by skyler (Beadle) on Feb 25, 2003 at 02:11 UTC
    Thanks for your help!!! I didn't think of it, but each file that I'm copying to the new directory has the same name called "word1.rtf" I would need to rename each file because if not they will not copy with the same name. Have you seen anywhere or do you know of a method to rename files dynamicaly while you are copying files to another directory? I'll appreciate any suggestions. Thanks a lot

      All you need to do is

      copy( "C:\\somename", C:\\some_path\\some_other_name" )

      To generate the new names dynamically you use something like:

      # this is a test example my $name = 'doc.txt'; for ( 1 .. 10 ) { my $unique = get_unique_filename($name); $names{$unique}++; print "$unique\n"; } sub get_unique_filename { my $name = shift; $name =~ s/(\.[^\.]+)$//; my $ext = $1 ? $1 : ''; my $tries = ''; my $max_tries = 100; while ( not unique_name($name.$tries.$ext) ) { $tries++; die "Could not make a unique file name $name\n" if $tries > $m +ax_tries; } return $name.$tries.$ext; } # this tests if our name exists in the test hash # you need to test if the file exists here instead sub unique_name { my $name = shift; return defined $names{$name} ? 0 : 1; # return -e $name ? 0 : 1; }

      Without the demo code all you need is a single sub that looks like:

      sub get_unique_filename { my $name = shift; $name =~ s/(\.[^\.]+)$//; my $ext = $1 ? $1 : ''; my $tries = ''; my $max_tries = 100; while ( -e $name.$tries.$ext ) { $tries++; die "Could not make a unique file name $name\n" if $tries > $m +ax_tries; } return $name.$tries.$ext; }

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print