使用Perl比较两个目录

Kel*_*lly 1 perl

我是Perl的新手,请原谅我的无知,

这是我打算做的.

$ perl dirComp.pl dir1 dir2
Run Code Online (Sandbox Code Playgroud)

dir1和dir2是目录名称.

脚本dirComp.pl应该识别dir1和dir2中的内容是否相同.

我想出了一个算法

Store all the contents of dir1(recursively) in a list
Store all the contents of dir2 in another list
Compare the two list, if they are same - dir1 & dir2 are same else not.

my @files1 = readdir(DIR1h);
my @files2 = readdir(DIR2h);

    # Remove filename extensions for each list.

        foreach my $item (@files1) {
        my ( $fileName, $filePath, $fileExt ) = fileparse($item, qr/\.[^.]*/);
        $item = $fileName;
        }


        foreach my $item (@files2) {
        my ( $fileName, $filePath, $fileExt ) = fileparse($item, qr/\.[^.]*/);
        $item = $fileName;
        }
Run Code Online (Sandbox Code Playgroud)

在上述代码的帮助下,我无法递归遍历给定目录中的子目录.任何帮助,将不胜感激.

编辑:使用文件:DirCompare

#!/usr/bin/perl -w

use File::DirCompare;
use File::Basename;

if ($#ARGV < 1 )
{
        &usage;
}

my $dir1 = $ARGV[0];
my $dir2 = $ARGV[1];

File::DirCompare->compare($dir1,$dir2,sub {
        my ($a,$b) = @_;
        if ( !$b )
        {
                printf "Test result:PASSED.\n";
                printf "Only in %s : %s\n", dirname($a), basename($a);
        }elsif ( !$a ) {
                printf "Test result:PASSED.\n";
                printf "Only in %s : %s\n", dirname($b), basename($b);
        }else {
                printf "Test result:FAILED.\n";
                printf "Files $a and $b are different.\n";
        }
});
Run Code Online (Sandbox Code Playgroud)

我有一个目录结构如下,

dir1/                  dir2/
    --file1.txt            --file1.txt
    --file2.txt            --file2.txt
    --file3.cpp            --file3.cpp
Run Code Online (Sandbox Code Playgroud)

我正面临测试结果:失败.结果必须通过.任何人都可以纠正我吗?

谢谢

Sér*_*ino 5

您使用File :: DirCompare提供的示例按预期工作.

请记住,为每个目录中的每个唯一文件以及内容不同的每对文件调用回调子例程.具有相同的文件名是不够的,每个目录中每个文件的内容也必须完全相同.

此外,报告"PASSED"的情况根本不是成功的(根据您的定义),因为它们详细说明了其中一个目录中存在文件但不存在另一个目录的情况:意味着目录的内容是不一样.

这应该更接近你想要的:

#!/usr/bin/perl

use strict;
use warnings;

use File::DirCompare;
use File::Basename;

sub compare_dirs
{
  my ($dir1, $dir2) = @_;
  my $equal = 1;

  File::DirCompare->compare($dir1, $dir2, sub {
    my ($a,$b) = @_;
    $equal = 0; # if the callback was called even once, the dirs are not equal

    if ( !$b )
    {
      printf "File '%s' only exists in dir '%s'.\n", basename($a), dirname($a);
    }
    elsif ( !$a ) {
      printf "File '%s' only exists in dir '%s'.\n", basename($b), dirname($b);
    }
    else
    {
      printf "File contents for $a and $b are different.\n";
    }
  });

  return $equal;
}

print "Please specify two directory names\n" and exit if (@ARGV < 2);
printf "%s\n", &compare_dirs($ARGV[0], $ARGV[1]) ? 'Test: PASSED' : 'Test: FAILED';
Run Code Online (Sandbox Code Playgroud)