複数階層のディレクトリを再帰的にコピー
複数階層のディレクトリを再帰的にコピーするにはFile::Findモジュールを使用します。
use strict; use warnings; use File::Path 'mkpath'; use Fcntl; use File::Find 'find'; use File::Copy 'copy'; use Cwd 'getcwd'; # 準備( ディレクトリとファイルの作成 ) my $top_dir = "dir_20080601_$$"; my @dirs = ( "$top_dir/dir1", "$top_dir/dir1/dir1_1", "$top_dir/dir1/dir1_2", "$top_dir/dir2", ); for my $dir (@dirs) { eval{ mkpath $dir }; if (@!){ die "@!" } } my @files = ( "$top_dir/top.txt", "$top_dir/dir1/1.txt", "$top_dir/dir1/dir1_1/1_1.txt", "$top_dir/dir1/dir1_2/1_2.txt", "$top_dir/dir2/2.txt" ); for my $file (@files) { sysopen( my $fh, $file, O_WRONLY | O_CREAT | O_EXCL ) or die "$file を作成することができません。: $!"; close $fh; } print "準備: $top_dir を作成しました。\n\n"; # 再帰的なディレクトリコピーのサンプル print "1: ディレクトリを再帰的にコピーする。\n"; my $cur_dir = getcwd(); # File::Find は、内部で、chdir を繰り返すので、 # 絶対パスで、コピー先ディレクトリ名を作成。 my $dir_copy_to = "$cur_dir/dir_20080601_${$}_cp"; find(\&recursive_copy, $top_dir); print "$top_dir が、$dir_copy_to にコピーされました。\n"; # 再帰コピーするための関数 sub recursive_copy { # コピー元のファイルあるいはディレクトリ my $file_from = $_; # コピー元のトップディレクトリを # コピー先のトップディレクトリに # 置き換える。 my $file_to = $File::Find::name; $file_to =~ s#^$top_dir#$dir_copy_to#; if (-d $file_from) { # ディレクトリは、コピーできないので、同じ名前で作成。 mkdir $file_to or die "$file_to を作成することができません。\n"; } else{ copy $file_from, $file_to or die "$file_from を $file_to にコピーすることができません。\n"; } }
(参考)File::Path、File::Copy、eval、sysopen関数、Fcntl
複数階層のディレクトリを再帰的にコピーする
find(\&recursive_copy, $top_dir); # 再帰コピーするための関数 sub recursive_copy { # コピー元のファイルあるいはディレクトリ my $file_from = $_; # コピー元のトップディレクトリを # コピー先のトップディレクトリに # 置き換える。 my $file_to = $File::Find::name; $file_to =~ s#^$top_dir#$dir_copy_to#; if (-d $file_from) { # ディレクトリは、コピーできないので、同じ名前で作成。 mkdir $file_to or die "$file_to を作成することができません。\n"; } else { copy $file_from, $file_to or die "$file_from を $file_to にコピーすることができません。\n"; } }
ディレクトリを再帰的にコピーするには、File::Find モジュールを使って、ディレクトリの作成とファイルのコピーを繰り返します。トップディレクトリ以外の構成は、コピー元と同じなので、トップディレクトリ名だけを置きかえます。
ディレクトリは、コピーできないので、コピー先の名称で、作成してあげます。