如何使用Perl同步两个目录?

时间:2009-10-13 12:43:15

标签: perl

我的驱动器中有一个名为“Lib”的文件夹,里面包含很多文件,我有一个问题,这个“Lib”文件夹在驱动器的许多其他位置。我的Perl脚本必须复制最新更新的文件夹“Lib”中的内容并将其粘贴到“d:\ perl \ Latest_copy_of_Lib”文件夹中

例如,我在d:\functionsd:\abc以及许多其他地方都有一个Lib文件夹。我想在这些目录中找到每个文件的最新副本。因此,如果文件d:\functions\foo.txt上次修改时间为2009-10-12而d:\abc\foo.txt上次修改时间为2009-10-13,那么我希望将d:\abc中的版本复制到目标目录。

我使用了file :: find但是它在整个dir中搜索并复制了不是最新副本的内容。

3 个答案:

答案 0 :(得分:9)

我想你刚才描述了rsync。除非你在这里有某些奇怪的要求,否则我认为你不需要编写任何代码来执行此操作。我当然不会让Perl完成你所描述的工作。

答案 1 :(得分:2)

您需要使用File::Find来创建要移动的文件的哈希值。如果文件比已存储在散列中的路径更新,则仅将路径放入散列中的文件。这是一个简单的实现。请注意,Windows平台上可能存在问题,我不习惯使用File::Spec以跨平台方式处理文件和路径。

#!/usr/bin/perl

use warnings;
use strict;

use File::Find;
use File::Spec;

my %copy;

my @sources = qw{
    /Users/cowens/foo/Lib
    /Users/cowens/bar/Lib
    /Users/cowens/baz/Lib
};

find sub {
    my ($volume, $dir, $file) = File::Spec->splitpath($File::Find::name);
    my @dirs                  = File::Spec->splitdir($dir);
    my @base                  = ($volume); #the base directory of the file
    for my $dir (@dirs) {
        last if $dir eq 'Lib';
        push @base, $dir;
    }
    #the part that is common among the various bases
    my @rest = @dirs[$#base .. $#dirs]; 
    my $base = File::Spec->catdir(@base);
    my $rest = File::Spec->catfile(@rest, $file);

    #if we don't have this file yet, or if the file is newer than the one
    #we have
    if (not exists $copy{$rest} or (stat $File::Find::name)[9] > $copy{$rest}{mtime}) {
        $copy{$rest} = {
            mtime => (stat _)[9],
            base  => $base
        };
    }
}, @sources;

print "copy\n";
for my $rest (sort keys %copy) {
    print "\t$rest from $copy{$rest}{base}\n";
}

答案 2 :(得分:0)

如果您可以在库的单个位置进行标准化,然后使用以下某个位置:

设置PERL5LIB环境变量并添加

use lib 'C:\Lib';

perl -I C:\Lib myscript

其中任何一个都会为您提供您的任何脚本都能访问的lib目录的单个副本。