Как добавить префикс ко всем именам файлов в каталоге?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь добавить префикс к строке (reference_) к именам всех файлов *.bmp во всех каталогах, а также подкаталогах.При первом запуске шелкового сценария он создаст каталоги, а также подкаталоги, и в каждом подкаталоге будет храниться снимок экрана каждого мобильного приложения с .bmp расширение.

Когда я запускаю автоматический шелковый сценарий во второй раз, он снова создает файлы *.bmp во всех подкаталогах.Перед запуском сценария во второй раз я хочу добавить ко всем файлам *.bmp префикс строки. reference_.

Например first_screen.bmp к reference_first_screen.bmp, У меня есть структура каталогов, как показано ниже:

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

имея first_screen.bmp и first_screen.bmp файлы и т. д...

Может ли кто-нибудь мне помочь?

Как я могу поставить перед всеми именами файлов изображений префикс reference_ нить?

Когда я запускаю сценарий во второй раз, сценарий Perl в шелке возьмет оба изображения из подкаталога и сравнит их попиксельно.Я пытаюсь использовать код ниже.Не могли бы вы подсказать мне, как мне приступить к выполнению этой задачи?

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

Я попробовал открытый вызов в режиме «+<», но получаю ошибку компиляции для режима чтения и записи.Когда я запускаю этот код, он показывает файлы в папке BG_images со строкой с префиксом, но на самом деле он не обновляет файлы в подкаталогах.

Это было полезно?

Решение

Вы не открываете каталог для записи.Просто используйте открытый каталог без частей режима строки:

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

Однако вам это не нужно.Вы можете использовать File::Find, чтобы составить список нужных файлов.

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

Другие советы

Вам, вероятно, стоит проверить Файл::Найти модуль для этого — он упростит рекурсию вверх и вниз по дереву каталогов.

Вероятно, вам следует сканировать имена файлов и изменять те, которые не начинаются с reference_ так что они делают.Для этого может потребоваться разделить имя файла на имя каталога и имя файла, а затем добавить к части имени файла префикс reference_.Это сделано с помощью Файл::Базовое имя модуль.

В какой-то момент вам нужно решить, что произойдет, когда вы запустите скрипт в третий раз.Сделайте файлы, которые уже начинаются с reference_ перезаписываются, или файлы без префиксов перезаписываются, или что?

Причина, по которой файлы не переименовываются, заключается в том, что операция переименования закомментирована.Не забудьте добавить use strict; в верхней части вашего скрипта (а также -w вариант, который вы использовали).

Если вы получили список файлов в массиве @files (и имена являются базовыми, поэтому вам не придется возиться с File::Basename), тогда цикл может выглядеть так:

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

С помощью find полезность от coreutils для Windows:

$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top