2009-01-02 22 views
3

J'essaie de préfixer une chaîne (reference_) aux noms de tous les fichiers * .bmp dans tous les répertoires ainsi que les sous-répertoires. La première fois que nous exécuterons le script en soie, il créera des répertoires ainsi que des sous-répertoires, et sous chaque sous-répertoire, il stockera le sceenshot de chaque application mobile avec l'extension .bmp.Comment puis-je ajouter un préfixe à tous les noms de fichiers dans un répertoire?

Lorsque j'exécute le silboxcript automatisé pour la deuxième fois, il crée de nouveau les fichiers * .bmp dans tous les sous-répertoires. Avant d'exécuter le script pour la deuxième fois, je veux préfixer tous les * .bmp avec une chaîne reference_.

Par exemple first_screen.bmp-reference_first_screen.bmp, J'ai la structure de répertoire comme ci-dessous:

C:\Image_Repository\BG_Images\second 
... 
C:\Image_Repository\BG_Images\sixth 

ayant first_screen.bmp et fichiers, etc ... first_screen.bmp

Quelqu'un pourrait-il me aider?

Comment puis-je préfixer tous les noms de fichiers d'image avec reference_ chaîne? Lorsque j'exécute le script pour la deuxième fois, le script Perl en soie prend les deux images du sous-répertoire et les compare pixel par pixel. J'essaye avec le code ci-dessous. Pourriez-vous me guider comment puis-je procéder pour terminer cette tâche?

#!/usr/bin/perl -w 
&one; 

&two; 

sub one { 

    use Cwd; 

    my $dir ="C:\\Image_Repository"; 
    #print "$dir\n"; 
    opendir(DIR,"+<$dir") or "die $!\n"; 
    my @dir = readdir DIR; 
    #[email protected]; 
    delete $dir[-1]; 
    print "$lines\n"; 
    foreach my $item (@dir) 
    { 
     print "$item\n"; 
    } 
    closedir DIR; 
} 

sub two { 

    use Cwd; 

    my $dir1 ="C:\\Image_Repository\\BG_Images"; 
    #print "$dir1\n"; 
    opendir(D,"+<$dir1") or "die $!\n"; 
    my @dire = readdir D; 
    #[email protected]; 
    delete $dire[-1]; 
    #print "$lines\n"; 
    foreach my $item (@dire) 
    { 
     #print "$item\n"; 
     $dir2="C:\\Image_Repository\\BG_Images\\$item"; 
     print $dir2; 
     opendir(D1,"+<$dir2") or die " $!\n"; 
     my @files=readdir D1; 
     #print "@files\n"; 
     foreach $one (@files) 
     { 
      $one="reference_".$one; 
      print "$one\n"; 
      #rename $one,Reference_.$one; 
     } 
    } 
    closedir DIR; 
} 

J'ai essayé appel ouvert avec le mode « + < » mais je reçois erreur de compilation pour le mode de lecture et d'écriture. Lorsque j'exécute ce code, il affiche les fichiers dans le dossier BG_images avec la chaîne préfixée, mais en fait il ne met pas à jour les fichiers dans les sous-répertoires.

+0

Je n'arrive pas à comprendre ce que vous demandez ici. Votre texte dit une chose mais votre code montre autre chose. –

Répondre

3

Vous ne pas ouvrir un répertoire pour l'écriture. Il suffit d'utiliser opendir sans que les parties en mode de la chaîne:

opendir my($dir), $dirname or die "Could not open $dirname: $!"; 

Cependant, vous n'avez pas besoin de cela. Vous pouvez utiliser File :: Find pour créer la liste des fichiers dont vous avez besoin.

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

use File::Basename; 
use File::Find; 
use File::Find::Closures qw(find_regular_files); 
use File::Spec::Functions qw(catfile); 


my($wanted, $reporter) = find_regular_files; 
find($wanted, $ARGV[0]); 


my $prefix = 'recursive_'; 


foreach my $file ($reporter->()) 
    { 
    my $basename = basename($file); 

    if(index($basename, $prefix) == 0) 
     { 
     print STDERR "$file already has '$prefix'! Skipping.\n"; 
     next; 
     } 

    my $new_path = catfile( 
     dirname( $file), 
     "recursive_$basename" 
     ); 

    unless(rename $file, $new_path) 
     { 
     print STDERR "Could not rename $file: $!\n"; 
     next; 
     } 

    print $file, "\n"; 
    } 
3

Vous devriez probablement vérifier le module File::Find pour cela - cela facilitera le récursif dans l'arborescence des répertoires.

Vous devriez probablement scanner les noms de fichiers et modifier ceux qui ne commencent pas par reference_ afin qu'ils le fassent. Cela peut nécessiter de diviser le nom de fichier en un nom de répertoire et un nom de fichier, puis en préfixant la partie du nom de fichier avec reference_. C'est fait avec le module File::Basename. À un certain point, vous devez décider de ce qui se passe lorsque vous exécutez le script pour la troisième fois à un moment ou à un autre. Les fichiers qui commencent déjà par reference_ sont-ils écrasés ou les fichiers non préfixés sont-ils écrasés ou quoi?

La raison pour laquelle les fichiers ne sont pas renommés est que l'opération de renommage est mise en commentaire. N'oubliez pas d'ajouter use strict; en haut de votre script (ainsi que l'option -w que vous avez utilisée).

Si vous obtenez une liste de fichiers dans un tableau @files (et les noms sont des noms de base, de sorte que vous ne devez pas jouer avec File :: Basename), la boucle pourrait ressembler à:

foreach my $one (@files) 
    { 
     my $new = "reference_$one"; 
     print "$one --> $new\n"; 
     rename $one, $new or die "failed to rename $one to $new ($!)"; 
    } 
0

Avec l'aide de find utilitaire à partir coreutils for Windows:

$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)" 
+0

Pourquoi pas: trouver -iname '* .bmp' -exec mv '{}' référence _ '{}' \; #? Je ne connais pas Perl alors je n'ai aucune idée de ce que fait la deuxième extrémité de la pipe (et je ne comprenais pas vraiment la question de l'OP, non plus ...). – strager

+0

@strager: Considérez la différence: dirname/img.bmp -> dirname/reference_img.bmp et dirname/img.bmp -> reference_dirname/img.bmp – jfs

Questions connexes