использование perl's File :: Xcopy для копирования каталога, игнорирующего файлы с использованием регулярных выражений - PullRequest
0 голосов
/ 09 сентября 2011

В Perl xcopy есть метод fn_pat для указания регулярного выражения для сопоставления с образцом, и я хочу использовать это для рекурсивного копирования каталога, игнорируя все файлы / папки, в которых содержится любая из этих строк:

.svn
build
test.blah

Я спотыкаюсь о синтаксисе, чтобы сделать это, я просмотрел много руководств по регулярным выражениям perl, но за свою жизнь я просто не могу освоить его. Я ценю любую помощь.

Спасибо.

... обновить ...

Я нашел регулярное выражение perl, которое, кажется, работает, но не с xnopy's fn_pat. Не уверен, что это ошибка в xcopy или мое выражение неверно, однако мои тесты показывают, что все в порядке.

$exp = '^(?!.*(\.svn|build|test\.blah)).*$';
if( '/dev/bite/me/.svn' =~ $exp ){ print "A\n"; }
if( '/dev/bite/me/.svn/crumbs' =~ $exp ){ print "B\n"; }
if( '/dev/build/blah.ext' =~ $exp ){ print "C\n"; }
if( '/dev/crap/test.blah/bites' =~ $exp ){ print "D\n"; }
if( '/dev/whats/up.h' =~ $exp ){ print "E\n"; }

только E печатает, как я и надеялся. Мне интересно знать, если это правильно или нет, а также любые идеи, почему он не работает с xcopy.

1 Ответ

1 голос
/ 09 сентября 2011

Здесь File::Xcopy звонит File::Find::finddepth:

sub find_files {
    my $self = shift;
    my $cls  = ref($self)||$self; 
    my ($dir, $re) = @_;
    my $ar = bless [], $cls; 
    my $sub = sub { 
        (/$re/)
        && (push @{$ar}, {file=>$_, pdir=>$File::Find::dir,
           path=>$File::Find::name});
    };
    finddepth($sub, $dir);
    return $ar; 
}

Здесь $re - ваше регулярное выражение.

Согласно File::Find документам, $_ будетустановить только конечное имя просматриваемого файла, если не используется опция no_chdir.

Единственный способ увидеть, как опция no_chdir передается finddepth, - это monkey-patch File::Xcopy::finddepth:

use File::Xcopy;

*{"File::Xcopy::finddepth"} = sub {
    my ($sub, $dir) = @_;
    File::Find::finddepth({ no_chdir => 1, wanted => $sub}, $dir);
};
...