代码之家  ›  专栏  ›  技术社区  ›  Manu JCasso

如何在Perl中递归复制目录并过滤文件名?

  •  12
  • Manu JCasso  · 技术社区  · 17 年前

    5 回复  |  直到 17 年前
        1
  •  11
  •   Gavin Miller    15 年前

    我会这样做:

    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;
    }
    
        2
  •  9
  •   dwarring    17 年前

    另一个选项是File::Xcopy。顾名思义,它或多或少地模拟了windowsxcopy命令,包括其过滤和递归选项。

    从文件中:

        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");
    
        3
  •  5
  •   moritz    17 年前

    rsync (1) ,您应该使用它(例如通过 system() ).

    Perl的File::Copy有点不完整(例如,它不复制Unix系统上的权限),因此如果不想使用系统工具,请查看CPAN。大概 File::Copy::Recursive 可能有用,但我看不到任何排除选项。我希望别人有更好的主意。

        4
  •  1
  •   Niniki    17 年前

    我不知道如何使用副本进行排除,但您可以按照以下方式进行:

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

    一个经典的答案是 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 “如果这是你想要的。