简体   繁体   中英

How can I copy a directory except for all of the hidden files in Perl?

I have a directory hierarchy with a bunch of files. Some of the directories start with a . . I want to copy the hierarchy somewhere else, leaving out all files and dirs that start with a .

How can one do that?

I think what you want is File::Copy::Recursive 's rcopy_glob() :

rcopy_glob()

This function lets you specify a pattern suitable for perl's glob() as the first argument. Subsequently each path returned by perl's glob() gets rcopy()ied.

It returns and array whose items are array refs that contain the return value of each rcopy() call.

It forces behavior as if $File::Copy::Recursive::CPRFComp is true.

If you're able to solve this problem without Perl, you should check out rsync . It's available on Unix-like systems, on Windows via cygwin, and perhaps as a stand-alone tool on Windows. It will do what you need and a whole lot more.

rsync -a -v --exclude='.*' foo/ bar/

If you aren't the owner of all of the files, use -rOlt instead of -a .

Glob 默认忽略点文件。

perl -lwe'rename($_, "foo/$_") or warn "failure renaming $_: $!" for glob("*")'

The code below does the job in a simple way but doesn't handle symlinks, for example.

#! /usr/bin/perl

use warnings;
use strict;

use File::Basename;
use File::Copy;
use File::Find;
use File::Spec::Functions qw/ abs2rel catfile file_name_is_absolute rel2abs /;

die "Usage: $0 src dst\n" unless @ARGV == 2;
my($src,$dst) = @ARGV;

$dst = rel2abs $dst unless file_name_is_absolute $dst;
$dst = catfile $dst, basename $src if -d $dst;

sub copy_nodots {
  if (/^\.\z|^[^.]/) {
    my $image = catfile $dst, abs2rel($File::Find::name, $src);

    if (-d $_) {
      mkdir $image
        or die "$0: mkdir $image: $!";
    }
    else {
      copy $_ => $image
        or die "$0: copy $File::Find::name => $image: $!\n";
    }
  }
}

find \&copy_nodots => $src;
cp -r .??*

almost perfect, because it misses files beginning with . and followed by a single sign. like - .d or .e

echo .[!.] .??*

this is even better

or:

shopt -s dotglob ; cp -a * destination; shopt -u dotglob

I found File::Copy::Recursive 's rcopy_glob().

The following is what is showed in the docs but is deceptive.

use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);

it does not import rcopy_glob() and the only way I found to use it was to be explict as follows:

use File::Copy::Recursive;

File::Copy::Recursive::rcopy_glob("glob/like/path","dest/path");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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