Reputation: 529
I have two directory with lots of sub directories and files in it like
originalfolder > file1
file2
folder2 > file3
file4
folder3 > file1
updatedfolder > file1
file2
folder2 > file3
file4
folder3 > file1
I have to compare all files in a specific sub directory of originalfolder to same subdirectory in updatedfolder.
It means i have to extact all files from one subdirectory and then move to next subdirectory
But my code extracts all files within a folder.
CODE
use strict;
use warnings;
use File::Find::Rule;
my $path = "C:/a";
my @files = File::Find::Rule->file()
->name( '*.*' )
->in( $path);
my $path1 = "C:/b";
my @files1 = File::Find::Rule->file()
->name( '*.*' )
->in( $path1);
I can do the comparing file size part.
I just need help on traversing one sub directory at a time and extracting files into an array.
Window command will also do.. as i can run window command inside Perl if necessary
Upvotes: 0
Views: 390
Reputation:
You can limit the level of subdirectories. Try limiting it to 1 to search only a specific folder:
my @files = File::Find::Rule->file()
->name( '*.*' )
->maxdepth(1)
->in( $path);
Edit
A code snippet, that would compare two folders and its subfolders without looping through all the sub folders manually.
Try
perl compare.pl folder_1 folder_2
After saving compare.pl with the following content...
#!/usr/bin/perl
use strict;
use warnings;
use File::Find::Rule;
my $first_directory_info = { directory_name => $ARGV[0] };
my $second_directory_info = { directory_name => $ARGV[1] };
get_directory_info( $first_directory_info );
get_directory_info( $second_directory_info );
if(
something_is_wrong( $first_directory_info, $second_directory_info, 1 ) ||
something_is_wrong( $second_directory_info, $first_directory_info )
)
{
print "Something is wrong...\n";
}
else
{
print "Everything is fine...\n";
}
sub get_directory_info
{
my $directory_info = shift;
my $directory_name = $directory_info->{ directory_name };
foreach my $file ( map { $_ =~ /^$directory_name(.*)/; $1 } File::Find::Rule->file->in( $directory_name ) )
{
$directory_info->{ files }->{ $file }->{ file_size } = -s $directory_name.$file;
$directory_info->{ files }->{ $file }->{ writable } = -w $directory_name.$file;
}
}
sub something_is_wrong
{
my $first_directory_info = shift;
my $second_directory_info = shift;
my $check_attributes = shift;
my $result = 0; # we assume, everything is fine
foreach my $key ( keys( $first_directory_info->{ files } ) )
{
unless( $second_directory_info->{ files }->{ $key } )
{
print "$key is missing in ".$second_directory_info->{ directory_name }."\n";
$result = 1; # some is wrong
next;
}
if( $check_attributes )
{
if( $first_directory_info->{ files }->{ $key }->{ file_size } !=
$second_directory_info->{ files }->{ $key }->{ file_size } )
{
print "$key has different file size in ".$second_directory_info->{ directory_name }."\n";
$result = 1;
}
if( $first_directory_info->{ files }->{ $key }->{ writable } !=
$second_directory_info->{ files }->{ $key }->{ writable } )
{
print "$key has different permissions in ".$second_directory_info->{ directory_name }."\n";
$result = 1;
}
}
}
return $result;
}
exit;
Upvotes: 1
Reputation: 39395
This will return you the directories under "C:/a". The condition if -d $File::Find::name checks whether its a directory or file before pushing it into the @files array.
use File::Find qw(finddepth);
my $path = "C:/a";
my @files;
finddepth(sub {
return if($_ eq '.' || $_ eq '..');
push @files, $File::Find::name if -d $File::Find::name;
}, $path);
Upvotes: 1