【发布时间】:2010-09-18 15:53:54
【问题描述】:
如何复制包含子目录的目录,不包括与 Windows 系统上的某个正则表达式匹配的文件或目录?
【问题讨论】:
标签: perl recursion directory copy
如何复制包含子目录的目录,不包括与 Windows 系统上的某个正则表达式匹配的文件或目录?
【问题讨论】:
标签: perl recursion directory copy
我会这样做:
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;
}
【讨论】:
另一个选项是 File::Xcopy。顾名思义,它或多或少地模拟了 windows xcopy 命令,包括它的过滤和递归选项。
来自文档:
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");
【讨论】:
如果您碰巧在一个类 Unix 操作系统上并且可以访问 rsync (1),您应该使用它(例如通过 system())。
Perl 的 File::Copy 有点损坏(例如,它不会在 Unix 系统上复制权限),所以如果您不想使用系统工具,请查看 CPAN。也许File::Copy::Recursive 可能有用,但我没有看到任何排除选项。我希望其他人有更好的主意。
【讨论】:
我不知道如何对副本进行排除,但您可以按照以下方式进行处理:
ls -R1 | grep -v <regex to exclude> | awk '{printf("cp %s /destination/path",$1)}' | /bin/sh
【讨论】:
一个经典的答案是使用'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”。
【讨论】: