¿Cómo puedo agregar un prefijo a todos los nombres de archivos en un directorio?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Estoy intentando anteponer una cadena (reference_) a los nombres de todos los archivos *.bmp en todos los directorios y subdirectorios.La primera vez que ejecutamos el script de seda, creará directorios y subdirectorios, y debajo de cada subdirectorio almacenará la captura de pantalla de cada aplicación móvil con .bmp extensión.

Cuando ejecuto el Silkscript automatizado por segunda vez, volverá a crear los archivos *.bmp en todos los subdirectorios.Antes de ejecutar el script por segunda vez, quiero anteponer a todos los *.bmp una cadena. reference_.

Por ejemplo first_screen.bmp a reference_first_screen.bmp, Tengo la estructura del directorio como se muestra a continuación:

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

teniendo first_screen.bmp y first_screen.bmp archivos, etc...

¿Podría alguien ayudarme?

¿Cómo puedo anteponer todos los nombres de archivos de imágenes con reference_ ¿cadena?

Cuando ejecuto el script por segunda vez, el script Perl en seda tomará ambas imágenes del subdirectorio y las comparará píxel por píxel.Lo estoy intentando con el código siguiente.¿Podría guiarme sobre cómo puedo proceder para completar esta tarea?

#!/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;
}

Intenté abrir una llamada con el modo '+<' pero aparece un error de compilación para el modo de lectura y escritura.Cuando ejecuto este código, muestra los archivos en la carpeta BG_images con una cadena como prefijo, pero en realidad no actualiza los archivos en los subdirectorios.

¿Fue útil?

Solución

No abre un directorio para escribir. Simplemente use opendir sin las partes de modo de la cadena:

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

Sin embargo, no necesitas eso. Puede usar File :: Find para hacer la lista de archivos que necesita.

#!/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";  
    }

Otros consejos

Probablemente deberías consultar el Archivo :: Buscar para esto. hará que el recursivo hacia arriba y hacia abajo del árbol de directorios sea más simple.

Probablemente debería estar escaneando los nombres de archivo y modificando aquellos que no comienzan con reference_ para que lo hagan. Eso puede requerir dividir el nombre del archivo en un nombre de directorio y un nombre de archivo y luego prefijar la parte del nombre del archivo con use strict;. Eso se hace con el File :: Basename .

En algún momento, debe decidir qué sucede cuando ejecuta el script por tercera vez. ¿Se sobrescriben los archivos que ya comienzan con -w, o se sobrescriben los archivos no prefijados, o qué?

La razón por la que no se cambia el nombre de los archivos es porque la operación de cambio de nombre está comentada. Recuerde agregar @files en la parte superior de su secuencia de comandos (así como la opción <=> que utilizó).

Si obtiene una lista de archivos en una matriz <=> (y los nombres son nombres básicos, por lo que no tiene que jugar con File :: Basename), entonces el bucle podría verse así:

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

Con la ayuda de la utilidad 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top