Как скопировать каталог, включая вспомогательные каталоги, за исключением файлов или каталогов, которые соответствуют определенному регулярному выражению в системе Windows?
Как я могу скопировать каталог рекурсивно и фильтровать имена файлов в Perl?
Ответ 1
Я бы сделал что-то вроде этого:
use File::Copy;
sub copy_recursively {
my ($from_dir, $to_dir, $regex) = @_;
opendir my($dh), $from_dir or die "Could not open dir '$from_dir': $!";
for my $entry (readdir $dh) {
next if $entry =~ /$regex/;
my $source = "$from_dir/$entry";
my $destination = "$to_dir/$entry";
if (-d $source) {
mkdir $destination or die "mkdir '$destination' failed: $!" if not -e $destination;
copy_recursively($source, $destination, $regex);
} else {
copy($source, $destination) or die "copy failed: $!";
}
}
closedir $dh;
return;
}
Ответ 2
Другой вариант - File:: Xcopy. Как сказано в названии, он более или менее эмулирует команду xcopy Windows, включая ее параметры фильтрации и рекурсии.
Из документации:
use File::Xcopy;
my $fx = new File::Xcopy;
$fx->from_dir("/from/dir");
$fx->to_dir("/to/dir");
$fx->fn_pat('(\.pl|\.txt)$'); # files with pl & txt extensions
$fx->param('s',1); # search recursively to sub dirs
$fx->param('verbose',1); # search recursively to sub dirs
$fx->param('log_file','/my/log/file.log');
my ($sr, $rr) = $fx->get_stat;
$fx->xcopy; # or
$fx->execute('copy');
# the same with short name
$fx->xcp("from_dir", "to_dir", "file_name_pattern");
Ответ 3
Если вы оказались на Unix-подобной ОС и имеете доступ к rsync (1)
, вы должны использовать это (например, через system()
).
Файл Perl:: Копия немного сломана (например, она не копирует разрешения для систем Unix), поэтому, если вы не хотите использовать свои системные инструменты, посмотрите CPAN. Может быть, File::Copy::Recursive может быть полезен, но я не вижу никаких исключений. Надеюсь, у кого-то еще есть идея.
Ответ 4
Я не знаю, как сделать исключение с копией, но вы могли бы что-то сделать по строкам:
ls -R1 | grep -v <regex to exclude> | awk '{printf("cp %s /destination/path",$1)}' | /bin/sh
Ответ 5
Классический ответ будет использовать 'cpio -p
':
(cd $SOURCE_DIR; find . -type f -print) |
perl -ne 'print unless m/<regex-goes-here>/' |
cpio -pd $TARGET_DIR
Команда "cpio
" имеет дело с фактическим копированием, включая сохранение разрешений. Тройка "cd $SOURCE_DIR; find . ...
" связана с удалением ведущей части исходного пути из имен. Единственная проблема с этим вызовом 'find
' заключается в том, что он не будет следовать символическим ссылкам; вам нужно добавить '-follow
', если это вам нужно.