Как добавить префикс ко всем именам файлов в каталоге?
-
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 '$_': $!)"