Comment copier un répertoire de manière récursive et filtrer les noms de fichiers en Perl?

StackOverflow https://stackoverflow.com/questions/227613

Question

Comment copier un répertoire, y compris des sous-répertoires, à l'exclusion des fichiers ou des répertoires correspondant à une expression régulière donnée sur un système Windows?

Était-ce utile?

La solution

Je ferais quelque chose comme ça:

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

Autres conseils

Une autre option est File :: Xcopy. Comme son nom l'indique, il émule plus ou moins la commande windows xcopy, y compris ses options de filtrage et récursive.

À partir de la 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");

Si vous utilisez un système d'exploitation semblable à Unix et que vous avez accès à rsync (1) , vous devez l'utiliser (par exemple, via system () ).

File :: Copy de Perl est un peu cassé (il ne copie pas les permissions sur les systèmes Unix, par exemple), donc si vous ne voulez pas utiliser vos outils système, regardez CPAN. Peut-être que Fichier :: Copier :: Récursif pourrait être utile, mais Je ne vois aucune option d'exclusion. J'espère que quelqu'un d'autre a une meilleure idée.

Je ne sais pas comment faire une exclusion avec une copie, mais vous pouvez créer quelque chose dans le sens de:

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

Une réponse classique utiliserait ' cpio -p ':

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

La commande ' cpio ' traite de la copie proprement dite, y compris la conservation des autorisations. Le truc de ' cd $ SOURCE_DIR; trouver . ... 'traite de la suppression de la partie principale du chemin source des noms. Le seul problème avec cette invocation de ' find ' est qu'il ne suivra pas les liens symboliques; vous devez ajouter ' -follow ' si c'est ce que vous voulez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top