Como posso adicionar um prefixo para todos os nomes de arquivos em um diretório?
-
03-07-2019 - |
Pergunta
Eu estou tentando prefixar a string (reference_
) para os nomes de todos os arquivos * .bmp em todos os diretórios também sub-diretórios. A primeira vez que executar o script de seda, ele irá criar diretórios como subdiretórios bem, e sob cada subdiretório que armazenará sceenshot de cada aplicativo móvel com extensão .bmp
.
Quando eu executar o silkscript automatizado pela segunda vez ele voltará a criar arquivos do * .bmp em todos os subdiretórios. Antes de executar o script para o segundo tempo, quero prefixo todo o .bmp * com um reference_
string.
Por exemplo first_screen.bmp
para reference_first_screen.bmp
,
Eu tenho a estrutura de diretórios como abaixo:
C:\Image_Repository\BG_Images\second
...
C:\Image_Repository\BG_Images\sixth
tendo first_screen.bmp
e first_screen.bmp
arquivos etc ...
qualquer um poderia me ajudar?
Como posso prefixar todos os nomes de arquivo de imagem com corda reference_
?
Quando eu executar o script para o segundo tempo, o script Perl em seda terá ambas as imagens da sub-diretório e compará-los tanto pixel por pixel. Estou tentando com código abaixo. Você poderia por favor me orientar como posso proceder para concluir esta tarefa.
#!/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;
}
Eu tentei chamada aberta com o modo '+ <' mas eu estou recebendo erro de compilação para o modo de ler e escrever. Quando estou executando este código, ele mostra os arquivos em BG_images pasta com corda prefixado, mas na verdade ele não está atualizando os arquivos nos subdiretórios.
Solução
Você não abrir um diretório para a escrita. Basta usar opendir sem as partes do modo da string:
opendir my($dir), $dirname or die "Could not open $dirname: $!";
No entanto, você não precisa disso. Você pode usar Arquivo :: Find para fazer a lista de arquivos que você precisa.
#!/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"; }
Outras dicas
Você provavelmente deve verificar o href="http://perldoc.perl.org/File/Find.html" rel="nofollow noreferrer"> arquivo módulo para isso - vai fazer recursão cima e para baixo da árvore de diretórios simples.
Você provavelmente deve ser a digitalização dos nomes de arquivos e modificar aqueles que não começar com reference_
de modo que eles fazem. Isso pode exigir a divisão do nome do arquivo acima em um nome de diretório e um nome de arquivo e, em seguida, prefixar a parte do nome de arquivo com reference_
. Isso é feito com o File :: módulo baseName .
Em algum momento, você precisa decidir o que acontece quando você executar o script pela terceira vez. Será que os arquivos que já começam com reference_
ser substituídas, ou fazer os arquivos unprefixed ser substituídas, ou o quê?
A razão os arquivos não estão sendo renomeado é que a operação de mudança de nome é comentado. Lembre-se de adicionar use strict;
no topo do seu script (assim como a opção -w
que você fez uso).
Se você receber uma lista de arquivos em uma @files
array (e os nomes são nomes de base, para que você não tem que mexer com File :: baseName), em seguida, o loop pode parecer:
foreach my $one (@files)
{
my $new = "reference_$one";
print "$one --> $new\n";
rename $one, $new or die "failed to rename $one to $new ($!)";
}
Com a ajuda de utilidade find
de coreutils para Windows :
$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"