2008-10-22 59 views

回答

11

我會做這樣的事情:

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; 
} 
+0

我認爲你有一個問題(無限循環),如果你的$ regexp不匹配「。」或「..」,它們是readdir返回的$ entry的前兩個值。 如果你的$ to_dir不存在,並且$ source確實是一個目錄,mkdir將會失敗,我建議使用mkpath來代替。 – huitseeker 2009-08-12 19:30:23

1

我不知道該怎麼做一個副本的排斥,但你可以再商量了沿着線:

ls -R1 | grep -v <regex to exclude> | awk '{printf("cp %s /destination/path",$1)}' | /bin/sh 
5

如果你碰巧是一個類Unix操作系統,並獲得到rsync (1),你應該使用它(例如通過system())。

Perl的File :: Copy有點壞(例如,它不會在Unix系統上覆制權限),所以如果您不想使用系統工具,請查看CPAN。也許File::Copy::Recursive可能是有用的,但我沒有看到任何排除選項。我希望別人有更好的主意。

9

另一種選擇是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"); 
1

一個經典的答案會用 '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'。

+0

確實在Windows的工作嗎? – Manu 2008-10-22 22:22:13

相關問題