Como posso adicionar um prefixo para todos os nomes de arquivos em um diretório?

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

  •  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.

Foi útil?

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 '$_': $!)"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top