2010-03-31 7 views
3

double possible: Renaming and Moving Files in Bash or PerlComment vérifier le fichier existe et renomme en Perl

Je suis un peu novice à Perl et la recherche d'un script qui va gérer le fichier en mouvement.

#!/usr/bin/perl -w 
$filename = 'DUMBFILE'; 
$destination = '/some/location/'; 
if (-e $destination + $filename) { 
    print "File Exists ! Renaming .."; 
    move ('/tmp/' + $filename, $destination + $filename + '.1'); 
} else { 
    move ('/tmp/' + $filename, $destination + $filename); 
} 

Je suis en mesure de le renommer en 1, mais je veux renommer progressivement, comme si existe fichier.1, renommer 0,2 et 0,3 si 0,2 existe. EDIT: et conserver l'extension identique; comme file.exe devient file.exe.1, file.exe.2 etc.

+5

concaténation de chaîne en Perl est réalisée à l'aide '' .' pas + '. Il vaut mieux utiliser 'Path :: Class' ou' File :: Spec' pour former des chemins à partir de composants individuels. Enfin, la logique de votre script n'est pas claire. Vous semblez écraser '/ some/location/DUMBFILE.1' avec'/tmp/DUMBFILE'. –

+0

Il s'agit d'un doublon de http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919. (ignorer "bash" dans le sujet - l'OP dit que perl était bien) - la réponse acceptée fournit le script pour le déplacement – DVK

Répondre

3
#!/usr/bin/perl 
use strict; 
use warnings; 

use File::Spec::Functions qw'catfile'; 
use File::Copy qw'move'; 
use autodie qw'move'; 

my $filename = 'DUMBFILE'; 
my $origin  = '/tmp'; 
my $destination = '/some/location'; 

my $path = catfile $destination, $filename; 
{ 
    my $counter; 
    while(-e $path){ 
    $counter++; 
    $path = catfile $destination, "$filename.$counter"; 
    } 
} 

move(catfile($origin, $filename), $path); 
+0

Idem avec maintien de l'extension? (Voir mon autre commentaire) – Disco

+0

@Disco, peut-être que vous devriez éditer votre question. –

+0

http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919 a la réponse avec maintien de l'extension – DVK

4

Vous devez concaténation . au lieu de +:

if (-e $destination . $filename) { 

Ou encore mieux. Vous pouvez utiliser le module File::Spec:

use File::Spec; 
... 
if (-e File::Spec->join($destination, $filename)) { 

Et s'il vous plaît use strict;

Pour déplacer le fichier que vous pouvez utiliser le module File::Copy:

use File::Copy; 
... 
move($from, $to); 
+0

Cela ne répond toujours pas la partie de base de la question - le compteur incrémental ajouté au nom. – Cascabel

4

probablement ce que vous voulez faire est quelque chose comme:

use File::Copy; 

sub construct_filename { 
    my ($dir, $name, $counter) = @_; 
    if ($name =~ /^(.*)\.(.*)$/) { 
     return "$dir/$1.$counter.$2"; 
    } else { 
     return "$dir/$name.$counter"; 
    } 
} 

if (-e "$destination$filename") { 
    $counter = 1; 
    while (-e construct_filename($destination,$filename,$counter)) { 
     $counter++; 
    } 
    move("/tmp/$filename", construct_filename($destination,$filename,$counter)); 
} else { 
    move("/tmp/$filename", "$destination$filename"); 
} 

De plus, la concaténation Perator en Perl est ., pas +. Ce que vous avez écrit ne va pas fonctionner du tout. Dans ce cas, vous pouvez simplement utiliser l'interpolation de chaîne entre guillemets doubles, et ne pas déranger avec la concaténation.

Et pour ce que ça vaut, une convention plus facile est que les répertoires ne contiennent jamais de barres obliques et de toujours les utiliser lorsque vous construisez des noms de fichiers (par exemple "$destination/$filename"). Comme d'autres l'ont souligné, la façon la plus robuste de construire le chemin est avec File::Spec. D'après ce que je pouvais dire, cependant, la partie que vous cherchiez vraiment était comment faire le nommage incrémental; donc j'ai donné une version claire et courte de cela. Passez à File::Spec comme bon vous semble!

+3

Il existe une condition de concurrence entre la vérification de $ filename et l'utilisation de $ filename. Ce ne sera probablement jamais un problème mais mérite d'être connu. –

+0

@Josh Kelley: Merci, je voulais mentionner cela, mais j'ai oublié quand j'ai fini. – Cascabel

+0

Merci, ça marche ... mais maintenant je vois que je ne veux pas renommer le fichier en .1 mais garder l'extension à la place. Comme si 'file.exe' était renommé en 'fichier.1.exe' 'fichier.2.exe' etc ... – Disco

2
#!/usr/bin/perl -w 
$filename = 'DUMBFILE'; 
$destination = '/some/location/'; 
$filepath=$destination.$filename; 
if (-e $filepath) { 
    print "File Exists ! Renaming .."; 
    $counter++; 
    rename('/tmp/'.$filename.$filepath.$counter); 
} else { 
    move ('/tmp/'.$filename.$filepath); 
} 
Questions connexes