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

发布于 2024-07-08 10:49:44 字数 54 浏览 6 评论 0原文

如何在 Windows 系统上复制包含子目录(不包括与某个正则表达式匹配的文件或目录)的目录?

How do I copy a directory including sub directories excluding files or directories that match a certain regex on a Windows system?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

海的爱人是光 2024-07-15 10:49:45

我会做这样的事情:

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

I'd do something like this:

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;
}
睫毛上残留的泪 2024-07-15 10:49:45

另一个选项是 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");

Another option is File::Xcopy. As the name says, it more-or-less emulates the windows xcopy command, including its filtering and recursive options.

From the documentation:

    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");
时常饿 2024-07-15 10:49:45

如果您碰巧使用的是类 Unix 操作系统并且可以访问 rsync (1),您应该使用它(例如通过 system())。

Perl 的 File::Copy 有点损坏(例如,它不复制 Unix 系统上的权限),因此如果您不想使用系统工具,请查看 CPAN。 也许 File::Copy::Recursive 可能有用,但是我没有看到任何排除选项。 我希望其他人有更好的主意。

If you happen to be on a Unix-like OS and have access to rsync (1), you should use that (for example through system()).

Perl's File::Copy is a bit broken (it doesn't copy permissions on Unix systems, for example), so if you don't want to use your system tools, look at CPAN. Maybe File::Copy::Recursive could be of use, but I don't see any exclude options. I hope somebody else has a better idea.

眼趣 2024-07-15 10:49:45

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

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

I don't know how to do an exclusion with a copy, but you could work something up along the lines of:

ls -R1 | grep -v <regex to exclude> | awk '{printf("cp %s /destination/path",$1)}' | /bin/sh
寄与心 2024-07-15 10:49:45

经典的答案是使用“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”的唯一问题是它不会遵循符号链接; 如果您想要的话,您需要添加“-follow”。

A classic answer would use 'cpio -p':

(cd $SOURCE_DIR; find . -type f -print) |
perl -ne 'print unless m/<regex-goes-here>/' |
cpio -pd $TARGET_DIR

The 'cpio' command deals with the actual copying, including permission preservation. The trick of 'cd $SOURCE_DIR; find . ...' deals with removing the leading part of the source path from the names. The only problem with that invocation of 'find' is that it won't follow symlinks; you need to add '-follow' if that's what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文