Come posso aggiungere un prefisso a tutti i nomi di file in una directory?
-
03-07-2019 - |
Domanda
Sto cercando di aggiungere un prefisso a una stringa (reference_
) ai nomi di tutti i file * .bmp in tutte le directory e anche nelle sottodirectory. La prima volta che eseguiamo la sceneggiatura di seta, creerà directory e sottodirectory, e sotto ogni sottodirectory memorizzerà il sceenshot di ogni applicazione mobile con .bmp
estensione.
Quando eseguo il silkscript automatizzato per la seconda volta, creerò nuovamente i file * .bmp in tutte le sottodirectory. Prima di eseguire lo script per la seconda volta, voglio aggiungere un prefisso a tutti * .bmp con una stringa first_screen.bmp
.
Ad esempio da reference_first_screen.bmp
a <=>,
Ho la struttura delle directory come di seguito:
C:\Image_Repository\BG_Images\second
...
C:\Image_Repository\BG_Images\sixth
con <=> e <=> file ecc ...
Qualcuno potrebbe darmi una mano?
Come posso aggiungere il prefisso a tutti i nomi dei file immagine con <=> stringa?
Quando eseguo lo script per la seconda volta, lo script Perl in silk prenderà entrambe le immagini dalla sottodirectory e le confronterà pixel per pixel. Sto provando con il codice qui sotto. Potete per favore guidarmi come posso procedere per completare questa attività.
#!/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;
}
Ho provato a aprire la chiamata con '+ <' ma sto ricevendo un errore di compilazione per la modalità di lettura e scrittura. Quando eseguo questo codice, mostra i file nella cartella BG_images con una stringa con prefisso ma in realtà non aggiorna i file nelle sottodirectory.
Soluzione
Non si apre una directory per la scrittura. Usa opendir senza le parti modalità della stringa:
opendir my($dir), $dirname or die "Could not open $dirname: $!";
Tuttavia, non è necessario. Puoi utilizzare File :: Trova per creare l'elenco dei file che ti servono.
#!/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"; }
Altri suggerimenti
Probabilmente dovresti dare un'occhiata al File :: Trova per questo - it renderà più semplice la ricorrenza su e giù dell'albero delle directory.
Probabilmente dovresti scansionare i nomi dei file e modificare quelli che non iniziano con reference_
in modo da farlo. Ciò potrebbe richiedere la suddivisione del nome del file in un nome di directory e un nome di file e quindi il prefisso della parte del nome del file con use strict;
. Questo è fatto con il File :: Basename .
Ad un certo punto, devi decidere cosa succede quando esegui lo script per la terza volta. I file che iniziano già con -w
vengono sovrascritti oppure i file non prefissati vengono sovrascritti o cosa?
Il motivo per cui i file non vengono rinominati è che l'operazione di ridenominazione viene commentata. Ricorda di aggiungere @files
nella parte superiore dello script (così come l'opzione <=> che hai utilizzato).
Se ottieni un elenco di file in un array <=> (e i nomi sono nomi di base, quindi non devi armeggiare con File :: Basename), il loop potrebbe apparire come:
foreach my $one (@files)
{
my $new = "reference_$one";
print "$one --> $new\n";
rename $one, $new or die "failed to rename $one to $new ($!)";
}
Con l'aiuto dell'utilità find
di coreutils per Windows :
$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"