Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Compare Directories and List Changed or Missing Files

by sierrathedog04 (Hermit)
on Aug 15, 2001 at 23:35 UTC ( [id://105157]=CUFP: print w/replies, xml ) Need Help??

Place this script in a target directory. Run the script, passing as a parameter the name of a source directory. This script will list all files which are in one directory but not the other and all files which are in both directories but have changed. Example: perl diffcompare.pl "/export/home/markj/cgi-bin"
# sierrathedog04, jonathansamuel@yahoo.com, August 2001 # place this script in the target directory and # pass it the name of the source directory from the # command line. # This utility requires that the diff command works on the user's syst +em. use strict; my $sourceDir = shift || die "Please pass the name of a source directo +ry enclosed in quotes. \n"; chomp $sourceDir; $sourceDir =~ s/\/\$/\$/; unless (-d $sourceDir) { die "$sourceDir is not a valid source directory. Please pass the n +ame of a valid source directory enclosed in quotes. \n"; } opendir THISDIR, "."; my @allFiles = readdir THISDIR; closedir THISDIR; foreach (@allFiles) { if (-e "$sourceDir/$_") { print "$_ in target differs from that in source directory $sou +rceDir\n" if `diff $_ $sourceDir/$_`; } else { print "$_ found in target but not in source directory $sourceD +ir\n"; } } print "\nFinished checking target\n"; opendir SOURCEDIR, $sourceDir; my @allSourceFiles = readdir SOURCEDIR; foreach (@allSourceFiles) { unless (-e "./$_") { print "$_ found in source directory $sourceDir but not in targ +et\n"; } }

Replies are listed 'Best First'.
Re: Compare Directories and List Changed or Missing Files
by Hofmator (Curate) on Aug 16, 2001 at 13:49 UTC

    Some suggestions:

    • You can use different delimiters in s///, so
      $sourceDir =~ s/\/\$/\$/; # is better written as $sourceDir =~ s#/\$#$#;
      btw, what is that supposed to do? It replaces a '/$' with a '$' sign, I see no obvious use for that ...
    • Instead of comparing files with a call to the external command diff - use File::Compare - it's portable and doesn't spawn an external process.

    -- Hofmator

      Thanks for the suggestions about an alternate delimiter and using File::Compare.

      The regex ought to have been:

      $sourceDir =~ s#/$##;

      which would have removed a trailing forward slash at the end of a directory name. What I actually wrote was, as you mention, pointless.

Modified Version 1.1
by sierrathedog04 (Hermit) on Aug 30, 2001 at 21:08 UTC
    This new version takes an optional second parameter which is the path of the target directory. It will thus compare the contents of the directory named in the first parameter with the contents of the directory named in the second parameter.

    If there is no second parameter then the program will compare the contents of the directory named in the first parameter with the contents of the current directory.

    NOTE: Modified on 9/13/01 to fix bugs and add minor functionality. See comments for additional functionality. Here is the updated code:

    # sierrathedog04, jonathansamuel@yahoo.com, August 2001 # First parameter is the target or VOB directory. # Optional second parameter is the source or current directory. # Ver. 1.1, Sept. 13, 2001. Now uses File::Compare instead of diff; # Modified printouts so only files are listed. (Not directories). use strict; require File::Compare; print "\n"; my $targetDir = shift || die "Please pass the name of a target directo +ry enclosed in quotes. \n"; chomp $targetDir; $targetDir =~ s#/$##; # Removes any trailing forward slash from the di +rectory. unless (-d $targetDir) { die "$targetDir is not a valid target directory. Please pass the n +ame of a valid target directory enclosed in quotes. \n"; } my $sourceDir = shift || "."; opendir THISDIR, $sourceDir; my @allFiles = grep { $_ ne '.' and $_ ne '..' && -f $_} readdir THIS +DIR; closedir THISDIR; foreach (@allFiles) { print "$_ in source directory $sourceDir differs from that in + target directory $targetDir\n\n" if File::Compare::compare("$sourceD +ir/$_", "$targetDir/$_") == 1; print "$_ found in source directory $sourceDir but not in targ +et directory $targetDir\n\n" if File::Compare::compare("$sourceDir/$_ +", "$targetDir/$_") < 0; } print "\n...Finished checking source.\n\n\n"; opendir targetDIR, $targetDir; my @alltargetFiles = grep { $_ ne '.' and $_ ne '..' && -f $_} readd +ir targetDIR; foreach (@alltargetFiles) { print "$_ found in target directory $targetDir but not in sour +ce directory $sourceDir\n\n" if File::Compare::compare("$sourceDir/$_ +", "$targetDir/$_") < 0; }
Ver. 1.2: Compare Directories and List Changed or Missing Files
by sierrathedog04 (Hermit) on Sep 19, 2001 at 21:03 UTC
    # sierrathedog04, jonathansamuel@yahoo.com, August 2001 + # First parameter is the target or VOB directory. + # Optional second parameter is the source or current directory. + + # Ver. 1.1, Sept. 13, 2001. Now uses File::Compare instead of diff; + # Modified printouts so only files are listed. (Not directories). + # Ver. 1.2 Sept. 19, 2001. Accepts optional parameters 'modified' and +'created' followed by directory names. If these parameters are used then the program wil +l copy all modified files to the modified directory and all changed files to the changed +directory. + use strict; + require File::Compare; + + use Getopt::Long; + my $modifiedDir; + my $createdDir; + GetOptions("modified:s" => \$modifiedDir, "created:s", => \$createdDir +); $| = 1; + + print "\n"; + my $targetDir = shift || die "Please pass the name of a target directo +ry enclosed in quotes. \n"; + chomp $targetDir; + $targetDir =~ s#/$##; # Removes any trailing forward slash from the di +rectory. unless (-d $targetDir) { + die "$targetDir is not a valid target directory.\nPlease pass the +name of a valid target directory enclosed in quotes. \n"; } my $sourceDir = shift || "."; unless (-d $sourceDir) { die "$sourceDir is not a valid source directory.\nPlease pass the +name of a valid source directory enclosed in quotes. \n"; } if (defined $modifiedDir){ unless (-d $modifiedDir) { die "$modifiedDir is not a valid modified directory. \ +nPlease use the --modified option to pass the name of a valid directo +ry \nto which you wish to copy all modified files."; } } if (defined $createdDir){ unless (-d $createdDir) { die "$createdDir is not a valid created directory. \nP +lease use the --created option to pass the name of a valid directory +\nto which you wish to copy all created files."; } } opendir THISDIR, $sourceDir; my @allFiles = grep { $_ ne '.' and $_ ne '..' && -f "$sourceDir/$_"} + readdir THISDIR; closedir THISDIR; foreach (@allFiles) { if (File::Compare::compare("$sourceDir/$_", "$targetDir/$_") = += 1) { print "$_ in source directory $sourceDir differs from + that in target directory $targetDir\n\n"; print `cp $sourceDir/$_ $modifiedDir/$_` if defined $ +modifiedDir; } elsif (File::Compare::compare("$sourceDir/$_", "$targetDir/$ +_") < 0) { print "$_ found in source directory $sourceDir but not + in target directory $targetDir\n\n"; print `cp $sourceDir/$_ $createdDir/$_` if defined $m +odifiedDir; } } print "\n...Finished checking source.\n\n\n"; opendir targetDIR, $targetDir; my @alltargetFiles = grep { $_ ne '.' and $_ ne '..' && -f $_} readd +ir targetDIR; foreach (@alltargetFiles) { print "$_ found in target directory $targetDir but not in sour +ce directory $sourceDir\n\n" if File::Compare::compare("$sourceDir/$_ +", "$targetDir/$_") < 0; }
      my @alltargetFiles = grep { $_ ne '.' and $_ ne '..' && -f $_} readdir targetDIR;
      ought to be
      my @alltargetFiles = grep { $_ ne '.' and $_ ne '..' && -f "$targetDir/$_"} readdir targetDIR;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://105157]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-23 15:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found