Как я могу синхронизировать две директории с Perl? - PullRequest
0 голосов
/ 13 октября 2009

У меня есть папка «Lib» на моем диске, она содержит много файлов внутри, и у меня проблема, что эта папка «Lib» есть во многих других местах на диске. Мой Perl-скрипт должен скопировать содержимое из папки "Lib", которая была обновлена ​​последним, и вставить ее в папку "d: \ perl \ Latest_copy_of_Lib"

Например, у меня есть папки Lib в d:\functions, d:\abc и во многих других местах. Я хочу найти последнюю копию каждого файла в этих каталогах. Итак, если файл d:\functions\foo.txt последний раз изменялся 2009-10-12, а d:\abc\foo.txt последний раз изменялся 2009-10-13, то я хочу, чтобы версия в d:\abc была скопирована в целевой каталог.

Я использовал file :: find, но он выполняет поиск по всему каталогу и копирует содержимое, которое не является последней копией.

Ответы [ 3 ]

9 голосов
/ 13 октября 2009

Я думаю, вы только что описали rsync. Если у вас нет каких-то странных требований, я не думаю, что вам нужно писать какой-либо код для этого. Я, конечно, не хотел бы, чтобы Perl выполнил работу, которую вы описали.

2 голосов
/ 13 октября 2009

Вам нужно использовать 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";
}
0 голосов
/ 13 октября 2009

Если вы можете стандартизировать в одном месте для своих библиотек, а затем использовать одно из следующего:

установить переменную среды PERL5LIB и добавить

use lib 'C:\Lib';

или

perl -I C:\Lib myscript

Любой из них даст вам одну копию вашей директории lib, к которой любой из ваших скриптов сможет получить доступ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...