in reply to Comparing Directories and copy files

Based on your description of what you're wanting to do, it looks like there are 2 potential problems that you might not have encountered yet.

First, the combination of opendir and readdir will list all contents of a directory, including ".", "..", and any subdirectories. Unless I missed it somewhere, your code is not excluding directories.

The second potential problem is the scenario of a file name that has a blank space in it. In that case, you would need to encapsulate the file's path within double-quotes in order for the DOS copy command to work. The same would be true if either directory had a blank space somewhere in the full path.

The code below should do what you want while avoiding the issues above. I've included comments to make it easier to follow what the code is doing. Also, note that I'm using backticks to submit DOS commands and store the output of those commands in a variable. (It's easy to confuse the backtick (`) and the single quote ('), which I have done in the past. :D)

use strict; use File::Copy; # Setup source and target directories my $source_dir = "c:\\perl_stuff\\appendix"; my $target_dir = "c:\\perl_stuff\\test"; # Setup dir commands my $cmd1 = "dir \/b \/a:-d ".$source_dir; my $cmd2 = "dir \/b \/a:-d ".$target_dir; # Get file list from dir command for source directory my $list1 = `$cmd1`; # Strip out blank lines $list1 =~ s/^\s*$//gm; # Get file list from dir command for target directory my $list2 = `$cmd2`; # Strip out blank lines $list2 =~ s/^\s*$//gm; # Dump the dir command outputs into arrays (my @files1) = (split /\n/,$list1); (my @files2) = (split /\n/,$list2); # Loop through array of file lists from source directory foreach my $file1 (@files1) { # If current file is not in target directory, copy it if (!(grep $_ eq $file1, @files2)) { # Setup variables will full path for the file to be copied my $file2 = $target_dir."\\".$file1; $file1 = $source_dir."\\".$file1; # Do the copy copy($file1,$file2) || die "Unable to copy '$file1' to '$file2 +': $!\n"; } }

Others may have more efficient methods for doing this, but this would be my approach. If you'd prefer to avoid the DOS dir command that I used, you can check out Win32API::File and it's GetFileAttributes function to exclude directories in obtaining file lists of the directories.

Hope this helps!