如何为目录下的所有文件名添加前缀?
Posted
技术标签:
【中文标题】如何为目录下的所有文件名添加前缀?【英文标题】:How can I add a prefix to all filenames under a directory? 【发布时间】:2010-09-29 05:10:27 【问题描述】:我正在尝试在所有目录以及子目录中的所有 *.bmp 文件的名称前添加一个字符串 (reference_
)。第一次运行 Silk 脚本时,它会创建目录和子目录,并且在每个子目录下会存储每个移动应用程序的屏幕截图,扩展名为 .bmp
。
当我第二次运行自动化 Silkscript 时,它将再次在所有子目录中创建 *.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_
字符串?
当我第二次运行该脚本时,Silk 中的 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;
我尝试使用 '+
【问题讨论】:
我不知道你在这里问什么。您的文字说明了一件事,但您的代码显示了其他内容。 【参考方案1】:您可能应该为此查看 File::Find 模块 - 它将使目录树的上下递归更简单。
您可能应该扫描文件名并修改那些不以reference_
开头的文件名,以便它们这样做。这可能需要将文件名拆分为目录名和文件名,然后在文件名部分添加前缀reference_
。这是通过File::Basename 模块完成的。
在某些时候,您需要决定第三次运行脚本时会发生什么。已经以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 ($!)";
【讨论】:
【参考方案2】:借助来自coreutils for Windows 的find
实用程序:
$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"
【讨论】:
为什么不:find -iname '*.bmp' -exec mv '' reference_'' \; #?我不知道 Perl,所以我不知道管道的第二端在做什么(我也无法真正理解 OP 的问题......)。 @strager:考虑区别:dirname/img.bmp -> dirname/reference_img.bmp 和 dirname/img.bmp -> reference_dirname/img.bmp【参考方案3】:您不会打开目录进行写作。只需使用 opendir 而不使用字符串的模式部分:
opendir my($dir), $dirname or die "Could not open $dirname: $!";
但是,你不需要那个。您可以使用 File::Find 来制作您需要的文件列表。
#!/usr/bin/perl 使用严格; 使用警告; 使用 File::Basename; 使用文件::查找; 使用 File::Find::Closures qw(find_regular_files); 使用 File::Spec::Functions qw(catfile); 我的($wanted,$reporter)=find_regular_files; 查找($通缉,$ARGV[0]); 我的 $prefix = 'recursive_'; foreach 我的 $file ( $reporter->() ) 我的 $basename = basename( $file ); 如果(索引($basename,$prefix)== 0) print STDERR "$file 已经有'$prefix'!跳过。\n"; 下一个; 我的 $new_path = catfile( 目录名($文件), “recursive_$basename” ); 除非(重命名 $file,$new_path ) print STDERR "无法重命名 $file: $!\n"; 下一个; 打印 $file, "\n";【讨论】:
以上是关于如何为目录下的所有文件名添加前缀?的主要内容,如果未能解决你的问题,请参考以下文章