Perl递归地复制特定格式的文件

时间:2014-05-21 19:40:57

标签: perl recursion file-io

注意:相关问题通过使用不推荐使用的模块解决,并且在操作系统中不一致。当前问题的答案使用了较新的模块,因此将在此处发布。

我有一个模块,它反过来使用File::NCopy CPAN模块递归复制文件。

问题是 - 我需要以递归方式将特定文件类型的文件复制到目标。有没有办法通过扩展过滤源?

作为替代方案 - 有没有办法复制除隐藏文件以外的所有文件?我的主要问题是.git文件夹也被复制 - 这是不可取的。

平台:MacOS

探索替代方案:

1)File :: Copy :: Recursive module: - 似乎只提供文件或目录的递归副本。似乎没有帮助隐藏文件或排除过滤器

2)使用rsync -avz --exclude ="。*" : - 无法将其与递归复制功能结合使用。

3)类似于How can I copy a directory recursively and filter filenames in Perl?的本土解决方案: - 可能是最后的手段 - 但除非经过不同平台的调整和测试,否则它们似乎不可移植。 除非模块已经存在,否则将退回到此。

4)https://metacpan.org/pod/Path::Class::Dir: - 看似合理 - 将使用此功能进行快速实施。

已实施解决方案:

我使用了递归模块和Path :: Class :: Dir

 dir($sourceDir)->recurse(callback => sub {
     my $file = shift;

     return if($file eq '.' || $file eq '..');

     return if -d $file;

     if (<custom filter>)
     {
         my $path = file($file)->relative($sourceDir);
         fcopy("$sourceDir/$path", "$destinationDir/$path") or die "Could not perform fcopy: $!";
     }
 });

没有相对路径 - 目标文件夹结构似乎与源文件夹结构不同。

1 个答案:

答案 0 :(得分:1)

我认为最简单的解决方案是使用File::Copy::Recursive完全复制目录结构,然后返回File::Find::Rule以确定要过滤的所有目录,然后将其删除。

鉴于.git个文件夹不一定能容纳那么多数据,我认为复制更多文件所带来的性能可能会非常小。以下内容足以实现您的目标:

use strict;
use warnings;

use File::Copy::Recursive qw(dircopy pathrmdir);
use File::Find::Rule;

my $src = '...src...';
my $dest = '...dest...';

dircopy($src, $dest) or die "Can't dircopy: $!";

my @git = File::Find::Rule->directory()
                          ->name('.git')
                          ->in($dest);

pathrmdir($_) or die "Can't remove $_: $!" for (@git);

或者,如果您想自己动手,可以查看File::Find::Rule #Further Examples,其中包含有关如何忽略CVS目录的示例&#34;。