再帰コピー

普通にUnix系の環境ならば"cp -pr"でいいし、そっちのほうが早いらしい。
でもそれだとWindows環境で動かん。
CPANが使えればFile::Copy::Recursiveで十分。
が、今回はCPANが使えないので実装してみた。

use strict;
use warnings;

use File::Find;
use File::Copy;

my $source_dir = shift @ARGV;
my $dest_dir = shift @ARGV;

my @files;
find sub{push(@files, $File::Find::name)}, $source_dir;

sub copy_entity{
  my $base  = shift;
  my $dest_path = $base;
  $dest_path =~ s|^\Q$source_dir\E|$dest_dir|;
  if(-d $base){
    mkdir $dest_path;
  } else {
    copy($base, $dest_path);
  }
}

map {copy_entity($_)} @files

ポイント

  • 標準モジュールは使えるのでFile::FindとFile::Copyを使用
  • コピー先のファイルパスを求める際の置換正規表現で"\Q...\E"を使用する。
    • この答えにたどり着くまで半日かかった。orz
    • "\Q...\E"でリテラル指定しないとものすごく悲しいことになる。
  • findのサブルーチンでコピーまでやらなかったのはわざと
    • とある理由からファイルリストを取得する必要があるため