ディレクトリを再帰的にコピーし、Perlでファイル名をフィルタリングするにはどうすればよいですか?
質問
Windowsシステム上の特定の正規表現に一致するファイルまたはディレクトリを除くサブディレクトリを含むディレクトリをコピーするにはどうすればよいですか
解決
次のようなことをします:
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ライクなOSで 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
'の呼び出しの唯一の問題は、シンボリックリンクをたどらないことです。必要に応じて「 -follow
」を追加する必要があります。
所属していません StackOverflow