简体   繁体   English

Perl:如何复制没有文件的目录?

[英]Perl: How to copy directory without any files?

I would like to copy one folder with subfolders but without the files.我想复制一个包含子文件夹但没有文件的文件夹。 With dircopy from package File::Copy::Recursive the whole structure with the files will be copy:使用来自dircopy File::Copy::Recursive的 dircopy,将复制包含文件的整个结构:

my $source = 'C:/dir_source';
my $target = 'C:/dir_target';

dircopy $source, $target or die "Could not perform dircopy of $source to $target: $!";

Is there an appropriate module or do I have use finddepth from module use File::Find;是否有合适的模块,或者我是否使用了模块use File::Find;中的finddepth and use rmdir?并使用 rmdir?

I don't know about libraries;我不知道图书馆; some probably exist which can be coerced into giving you that.有些可能存在,可以被迫给你那个。

Here's one way to do it, indeed using File::Find to find the hierarchy.这是一种方法,实际上是使用File::Find来查找层次结构。 Then go through that list of full-path locations and make them然后 go 通过完整路径位置列表并制作它们

use warnings;
use strict;
use feature 'say';

use File::Find;

sub get_dir_hier {
    my ($src) = @_; 

    my @dirs;
    find( sub { 
        push @dirs, $File::Find::name 
            if -d and $File::Find::name ne $src;  # only UNDER source dir
    }, $src); 

    return \@dirs;
}

sub copy_dir_hier {
    my ($dirs, $tgt, $verbose) = @_; 

    for my $dir (@$dirs) {
        next if not $dir;

        say "mkdir $tgt/$dir" if $verbose;
        # mkdir "$tgt/$dir"                    # UNCOMMENT AFTER TESTING
        #    or warn "Error with mkdir $tgt/$dir: $!";
    }   
}

my ($source_dir, $target_dir) = @ARGV;
die "Usage: $0 source-dir target-dir\n" 
    if not $source_dir or not $target_dir;

say "Copy directory hierarchy from under $source_dir to under $target_dir\n";

say "Find directory hierarchy under $source_dir"; 
my $dirs = get_dir_hier($source_dir);
say for @$dirs; say '-'x60;

say "\nCopy that hierarchy under $target_dir";
copy_dir_hier( $dirs, $target_dir, 1 );

This obtains the listing of directories under the given source directory, without it;这将获得给定源目录的目录列表,没有它; that is easily changed.这很容易改变。 Then those are copied under the target directory, which isn't made.然后将这些复制到未创建的目标目录下。

For making directories, the target directory (under which to make the hierarch) must exist for mkdir to work, since it doesn't create directories recursively;对于创建目录,目标目录(在其下创建层次结构)必须存在才能使mkdir工作,因为它不会递归地创建目录; the source's directory hierarchy is built by adding them in order so that is not a problem for the rest of hierarchy.源的目录层次结构是通过按顺序添加它们来构建的,因此对于层次结构 rest 来说这不是问题。

In order to create paths (recursively) see make_path in File::Path为了(递归地)创建路径,请参阅File::Path中的make_path

All code shown here has been tested and it works as it stands -- but it needs a lot more testing, and probably debugging.此处显示的所有代码都已经过测试并且可以按原样工作——但它需要更多的测试,可能还需要调试。


One other way is by using the Linux tree command.另一种方法是使用 Linux tree命令。

The tree command can be made into printing directories only, with the full path and without pretty graphics: tree -dfi . tree命令可以只打印目录,带有完整路径,没有漂亮的图形: tree -dfi With these options the default output of使用这些选项,默认的 output

$ tree t1
t1
├── f1.txt
├── t21
│   ├── f21a.txt
│   ├── f21.txt
│   └── t31
│       └── f3.txt
└── t22

turns into变成

$ tree -dfi t1
t1
t1/t21
t1/t21/t31
t1/t22

This is a convenient form for making those directories.这是制作这些目录的方便形式。

Here's a (barely-tested) code for finding the directory hierarchy this way:这是一个(几乎没有测试过的)代码,用于以这种方式查找目录层次结构:

# Uses "tree" command
sub get_dir_hier_using_tree {
    my ($src) = @_;

    my @out = qx(tree -dfi $src);

    my @dirs = grep { m{^/|\.} } @out;  #/ keep only directories (full path)
    chomp @dirs;
    #say for @dirs; say '---';

    # Remove the leading part of the path, to the source-directory name
    s{^$src/?}{} for @dirs;

    # Remove possibly empty entries
    @dirs = grep { defined and /\S/ } @dirs;
    #say for @dirs; say '-'x40;

    return \@dirs
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM