Как я могу синхронизировать две директории с Perl?

У меня есть папка «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, но он ищет весь каталог и копирует содержимое, которое не является последней копией.

13.10.2009 12:43:15
3 ОТВЕТА

Вам нужно использовать 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
13.10.2009 13:24:21
Привет, он берет копию всего содержимого из Lib и печатает ее. Это не нужно, если какое-либо обновление произошло в папке Lib в последнее время, он должен взять только эту копию в одиночку. скажем для ex, если одна папка Lib содержит a.txt, тогда я делаю изменение в d: \ abc \ Lib, помещая b.txt в этот путь, он должен искать в то время как dir и брать только b.txt, так как я удалил a.txt и заменяется на b.txt только в этом пути, а не во всех.
User1611 13.10.2009 13:59:58

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

9
13.10.2009 13:06:17
Возможно, он ограничен только использованием perl для этого? Не все находятся в вашей ситуации, когда они имеют немедленный доступ к любому открытому исходному коду в Интернете. Лично мне нужно выполнить задачу, аналогичную rsync, но из-за чрезмерного усердия я не могу свободно использовать ничего, кроме perl.
airbear 3.11.2014 02:09:30
Конечно, кажется странным, что кто-то будет доверять вам начать с нуля, чем использовать программу, которая практически пуленепробиваема, доступна прямо сейчас и часто легко устанавливается. Я думаю, что во многих из этих случаев (возможно, не в вашем) отсутствует должная мотивация для более высоких уровней управления. Скажите им, сколько денег они сэкономят. :)
brian d foy 3.11.2014 05:00:45
У вас есть точка зрения, и я действительно не могу с вами согласиться. Сказав это, некоторые корпорации впечатляюще непреклонны в том, чтобы вести себя настолько неэффективно и неэффективно, насколько это возможно.
airbear 3.11.2014 17:38:46

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

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

use lib 'C:\Lib';

или

perl -I C:\Lib myscript

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

0
13.10.2009 20:16:33