0

我试图找出 Perl 中两个目录之间的区别。我想优化它以高效运行,也不确定如何忽略某些文件(比如扩展名为 .txt 或 .o)

我到目前为止的代码是:

use strict;
use warnings;
use Parallel::ForkManager;
use File::Find;
use List::MoreUtils qw(uniq);

my $dir1 = "/path/to/dir/first";
my $dir2 = "/path/to/dir/second";
my @comps = ('abc');
my (%files1, %files2);
my $workernum = 500; 
my $pm = new Parallel::ForkManager($workernum);
my @common = ();
my @differ = ();
my @only_in_first = ();
my @only_in_second = ();

foreach my $comp (@comps) {
    find( sub { -f  ($files1{$_} = $File::Find::name) }, "$dir1");
    find( sub { -f  ($files2{$_} = $File::Find::name) }, "$dir2");
    my @all = uniq(keys %files1, keys %files2);
    for my $file (@all) {
        my $pid = $pm->start and next; # do the fork
        my $result;
        if ($files1{$file} && $files2{$file}) { # file exists in both dirs
            $result = qx(/usr/bin/diff -q $files1{$file} $files2{$file});
            if ($result =~m/^Common subdirectories/) {
                push (@common, $result);
            } else {
                push (@differ, $result);
            }
        } elsif ($files1{$file}) { 
            push (@only_in_first, $file);
        } else {
            push (@only_in_second, $file);
        }
        $pm->finish; # do the exit in child process
    }
}
4

2 回答 2

0

diff 实用程序有一个 -r 开关,允许它在子目录中工作。

对你来说还不够吗?

于 2013-09-18T09:04:54.953 回答
0

是的, diff -r 确实做了你的代码也做的事情。但是, diff -r 不适用于 500 个工作进程。然后再次 diff -r 可能足够快,它不需要并行处理 500 个进程。

注意事项:

  1. "$var" 很少需要,最好写成 $var
  2. 使用 2 个哈希作为差异,但仍然使用带有 2 个哈希键数组的 uniq() 是浪费内存和 CPU 周期
  3. 使用 diff -q 可以很容易地在 perl 中使自己变得容易,或者至少通过首先对两个文件进行 stat()'ing 并至少在进行 fork 之前比较大小来轻松加快速度。如果文件很小,可以使用 perl。
  4. 如果你真的想 diff -q 分叉,至少检查 $? 因为可能存在问题,例如查找或执行的位置。事实上,检查退出代码就足够了,而不是在 stdout/stderr 上执行 grep
  5. 为简单起见,使用从 PATH 中查找,而不是绝对路径
于 2013-09-18T20:22:35.040 回答