Comment puis-je ajouter un préfixe à tous les noms de fichiers d'un répertoire?

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

  •  03-07-2019
  •  | 
  •  

Question

J'essaie de faire précéder d'une chaîne (reference_) les noms de tous les fichiers * .bmp de tous les répertoires, ainsi que de leurs sous-répertoires. La première fois que nous exécutons ce script, celui-ci créera des répertoires ainsi que des sous-répertoires. Sous chaque sous-répertoire, il enregistrera l'image de chaque application mobile avec .bmp extension.

.

Lorsque j'exécutera le silkscript automatisé pour la deuxième fois, les fichiers * .bmp seront à nouveau créés dans tous les sous-répertoires. Avant d'exécuter le script pour la deuxième fois, je souhaite préfixer tous les * .bmp par une chaîne first_screen.bmp.

Par exemple reference_first_screen.bmp à <=>, J'ai la structure de répertoire ci-dessous:

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

ayant <=> et <=> fichiers etc ...

Quelqu'un pourrait-il m'aider?

Comment puis-je préfixer tous les noms de fichiers d'image avec <=> chaîne?

Lorsque je lance le script pour la deuxième fois, le script Perl en soie prendra les deux images du sous-répertoire et les comparera 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;
    #$lines=@dir;
    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;
    #$lines=@dire;
    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é l'appel ouvert avec '+ <' mais je reçois une erreur de compilation pour le mode lecture et écriture. Lorsque j'exécute ce code, il affiche les fichiers du dossier BG_images avec la chaîne préfixée, mais en réalité, il ne met pas à jour les fichiers des sous-répertoires.

Était-ce utile?

La solution

Vous n'ouvrez pas de répertoire pour l'écriture. Utilisez simplement opendir sans les parties mode de la chaîne:

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

Cependant, vous n’avez pas besoin de ça. Vous pouvez utiliser File :: Find pour faire 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";  
    }

Autres conseils

Vous devriez probablement consulter le module Fichier :: Rechercher pour cela - cela simplifiera le parcours dans l’arborescence des répertoires.

Vous devriez probablement analyser les noms de fichiers et modifier ceux qui ne commencent pas par reference_ afin qu'ils le fassent. Cela peut nécessiter de scinder le nom de fichier en un nom de répertoire et un nom de fichier, puis de préfixer la partie du nom de fichier avec use strict;. C’est fait avec le module Fichier :: Nom de base .

À un moment donné, vous devez décider de ce qui se passe lorsque vous exécutez le script pour la troisième fois. Les fichiers qui commencent déjà par -w sont-ils écrasés ou les fichiers sans préfixe sont-ils écrasés ou quoi?

La raison pour laquelle les fichiers ne sont pas renommés est que l'opération de changement de nom est commentée. N'oubliez pas d'ajouter @files en haut de votre script (ainsi que l'option <=> que vous avez utilisée).

Si vous obtenez une liste de fichiers dans un tableau <=> (et que les noms sont des noms de base, vous n'avez donc pas besoin de manipuler File :: Basename), la boucle peut alors ressembler à:

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

À l'aide de find l'utilitaire de coreutils pour Windows :

$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top