2010-06-25 5 views
0

J'utilise ce code pour traiter mes dossiers et fichiers avec deux sous-marins:
« sous dossiers » pour les noms de dossier que
« fichiers sous » pour les noms de fichiers avec des extensions Mais je me suis rendu compte que "sous-dossiers" mess avec mes fichiers avec des extensions pendant le processus de changement de nom. Comment distinguer les processus les uns des autres ou quelle est la manière intelligente de dire aux "sous-dossiers" de renommer "noms" sans extension et "sous-fichiers" de renommer "noms" avec externsion? File :: Find :: find() appelle votre sous pour chaque fichier et dossier.Perl Renommer des dossiers et des fichiers avec File :: Find

find(\&folders, $dir_source); 
sub folders { 
    my $fh = $File::Find::dir; 
    my $artist = (File::Spec->splitdir($fh))[3];   

    if (-d $fh) { 
     my $folder_name = $_; 

     # some substitution 

     rename $folder_name, $_; 
    } 
} 


find(\&files, $dir_source); 
sub files { 
    /\.\w+$/ or return; 
    my $fn = $File::Find::name; 

    my ($genre, $artist, $boxset, $album, $disc); 
    if ($fn =~ /Singles/ or $fn =~ /Box Set/) { 
     ($genre, $artist, $boxset, $album, $disc) = (File::Spec->splitdir($fn))[2..6]; 
    } 
    else { 
     ($genre, $artist, $album, $disc) = (File::Spec->splitdir($fn))[2..5]; 
    } 

    if (-e $fn) { 
     my $file_name = $_; 

     # some substitution 

     rename $file_name, $_; 
    } 
} 

Répondre

1

Si vous voulez seulement affecter les dossiers, alors ignorez les fichiers:

Et vous devrez appeler finddepth() au lieu de find(), puisque vous changez les noms de répertoire (vous voudrez renommer le "plus profond" répertoires avant les plus "superficiels").

finddepth(sub { 
    return unless -d; 

    (my $new = $_) =~ s/this/that/ or return; 
    rename $_, $new or warn "Err renaming $_ to $new in $File::Find::dir: $!"; 
}, "."); 

Alternative pour plusieurs substitutions:

finddepth(sub { 
    return unless -d; 

    my $new = $_; 
    for ($new) { 
    s/this/that/; 
    s/something/something_else/; 
    } 
    return if $_ eq $new; 

    rename $_, $new or warn "Err renaming $_ to $new in $File::Find::dir: $!"; 
}, "."); 

Et dans les fichiers sous, je ferais la première déclaration:

return unless -f; 
+0

Votre suggestion est impressionnant sans aucun doute. J'ai seulement des difficultés à passer plusieurs my $ new; ($ new = $ _) = ~ s/quelque chose/autre chose/ou retour; parce que cela ne fonctionne que quand un. – thebourneid

+0

Vous ne savez pas ce que vous voulez dire. Vous voulez faire plusieurs // sur la même variable et renommer si l'un d'eux change la valeur? – runrig

+0

Oui. Dans mon code complet, j'ai 10-15 s /// et si quelqu'un d'entre eux est rencontré dans N'IMPORTE O in dans n'importe quel dossier - renommer. Mais je suppose que lorsque "ou retour" est ajouté - il arrête le traitement si quelque chose n'est pas satisfait. Ai-je raison? – thebourneid

Questions connexes