Frage

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

War es hilfreich?

Lösung

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;

Andere Tipps

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top