Domanda

Come copio una directory che include sottodirectory escludendo file o directory che corrispondono a una certa regex su un sistema Windows?

È stato utile?

Soluzione

Farei qualcosa del genere:

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

Altri suggerimenti

Un'altra opzione è File :: Xcopy. Come dice il nome, emula più o meno il comando windows xcopy, incluso il filtro e le opzioni ricorsive.

Dalla documentazione:

    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");

Se ti trovi in ??un sistema operativo simile a Unix e hai accesso a rsync (1) , dovresti usarlo (ad esempio attraverso system () ).

Perl's File :: Copy è un po 'rotto (non copia i permessi sui sistemi Unix, per esempio), quindi se non vuoi usare i tuoi strumenti di sistema, guarda CPAN. Forse File :: Copia :: Ricorsivo potrebbe essere utile, ma Non vedo alcuna opzione di esclusione. Spero che qualcun altro abbia un'idea migliore.

Non so come fare un'esclusione con una copia, ma potresti lavorare su qualcosa come:

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

Una risposta classica userebbe ' cpio -p ':

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

Il comando ' cpio ' si occupa della copia effettiva, inclusa la conservazione delle autorizzazioni. Il trucco di ' cd $ SOURCE_DIR; trova . ... "si occupa di rimuovere la parte iniziale del percorso di origine dai nomi. L'unico problema con quell'invocazione di ' find ' è che non seguirà i symlink; devi aggiungere " -follow " se è quello che vuoi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top