use strict; use warnings; use File::Find; # for traversing directories with find() my %b_paths; # hash holding relative paths of files of the 'b' directory my @dirs = ('a', 'b'); # directories to investigate my $dirselect = 1; # use second @dirs entry # Populate the hash with paths from the second @dirs entry directory. # Use the relative paths as keys and 'undef' as value. chdir($dirs[$dirselect]); # traverse the directory tree find(sub { return if (!-f $_); # ignore directories and other non regular files # register the relative path in the hash # see File::Find documentation for $File::Find::dir and $_ # here name of current directory is $File::Find::dir # and name of directory entry is $_ $b_paths{"$File::Find::dir/$_"} = undef; }, '.'); chdir('..'); # switch to the first @dirs entry $dirselect = 0; chdir($dirs[$dirselect]); # For each path in the directory check, # whether it is also present in the 'b' directory. # This is done with a fast lookup in the hash %b_paths (set lookup) # Print the result along with the path # traverse the directory tree find(sub { return if (!-f $_); # ignore directories and other non regular files my $p = "$File::Find::dir/$_"; my $exists = exists $b_paths{$p} ? '' : ' not'; $p =~ s{^\.}{$dirs[$dirselect]}xms; # change the leading '.' for the base directory name print "Path $p does$exists exist in the '$dirs[1-$dirselect]' directory\n"; }, '.'); chdir('..'); #### use strict; use warnings; use File::Find; my %a_paths; # hash holding relative paths of files of the 'a' directory my %b_paths; # hash holding relative paths of files of the 'b' directory my @dirs = (['a', \%a_paths], ['b', \%b_paths]); my $dirselect = 1; # Populate the hash with paths from the second @dirs entry directory. # Use the relative paths as keys and 'undef' as value. chdir($dirs[$dirselect]->[0]); find(sub { return if (!-f $_); # ignore directories and other non regular files # register the relative paths in the hash # see File::Find documentation for $File::Find::dir and $_ # here name of current directory is $File::Find::dir # and name of directory entry is $_ $dirs[$dirselect]->[1]->{"$File::Find::dir/$_"} = undef; }, '.'); chdir('..'); # change to the parallel first @dirs entry $dirselect = 0; chdir($dirs[$dirselect]->[0]); # For each path in the directory check, # whether it is also present in the second directory. # This is done with an lookup in the hash of the other entry(set lookup) # Print the result along with the path # Populate the hash with paths from the directory. # Use the relative paths as keys and 'undef' as value. find(sub { return if (!-f $_); # ignore directories and other non regular files my $p = "$File::Find::dir/$_"; # register the relative paths in the hash $dirs[$dirselect]->[1]->{$p} = undef; my $exists = exists $b_paths{$p} ? '' : ' not'; $p =~ s{^\.}{$dirs[$dirselect]->[0]}xms; # change the leading '.' for the base directory name print "Path $p does$exists exist in the '$dirs[1-$dirselect]->[0]' directory\n"; }, '.'); chdir('..'); $dirselect = 1; # now find all entries in the second directory, that are unique for my $p (keys %{$dirs[$dirselect]->[1]}) { if (!exists $dirs[1-$dirselect]->[1]->{$p}) { $p =~ s{^\.}{$dirs[$dirselect]->[0]}xms; # change the leading '.' for the base directory name print "Path $p does not exist in the '$dirs[1-$dirselect]->[0]' directory\n"; } }