重命名和编号目录中的文件

时间:2013-11-04 17:40:37

标签: perl

我正在尝试重命名文件夹中的所有tif文件,并将它们从1编号为x。防爆。初始文件名“image-2.tif”和“image-3.tif”将重命名为“file1.tif”和“file2.tif”。

这是我的代码:

my $dirname = "../folder";
opendir (DIR, $dirname) or die "cannot open directory $dirname";
my @files = grep /.tif/, readdir DIR;
closedir (DIR);

my $basename = "file";
my $count = 1;
my $new;
foreach (@files) {
$new = "${basename}${count}.tif";
print "rename $_ ${basename}${count}.tif\n";
rename $_, $new;
$count++;
}

虽然所有文件都已正确读取,但它们不会重命名。

3 个答案:

答案 0 :(得分:3)

当您从另一个文件中获取文件时,您需要为rename()函数使用一个好的路径。模块File::Spec可以帮助实现它:

use File::Spec;

my $dirname = "../folder";
my $abs_path = File::Spec->rel2abs($dirname);

foreach (@files) {
    $new = "${basename}${count}.tif";
    print "rename $_ ${basename}${count}.tif\n";
    rename File::Spec->catfile($abs_path, $_), File::Spec->catfile($abs_path, $new);
    $count++;
}

答案 1 :(得分:2)

我建议改变你的行:

rename $_, $new;

...更像是:

rename($_, $new) or warn "rename: $_: $new: $!\n";

...你应该能够看到它无法正常工作 - 因为rename失败时会返回false$!会告诉你失败的原因)。

此外,rename操作的目标(在您的情况下:$new)也需要包含目录组件(否则,您尝试将文件移动到进程的当前工作目录中(可能不是你想要的))。

最后,我建议,不要将$dirname的值硬编码到相对路径,而应将其作为命令行参数接受。这允许您从任何$PWD运行脚本。请参阅@ARGV联机帮助页和/或内置perlvar命令中的shift

因此,像这样:

my $dirname = shift; # Accept dirname as commandline argument
opendir (DIR, $dirname) or die "cannot open directory $dirname";
my @files = grep /\.tif$/, readdir DIR; # Escape regex meta-char (.) and anchor to end of string ($).
closedir (DIR);

my $basename = "file";
my $count = 1;
my $new;
foreach (@files) {
    $new = "${dirname}/${basename}${count}.tif"; # Include dirname in target path
    print "rename $_ $new\n";
    rename($_, $new) or warn "rename: $_: $new: $!\n"; #warn when rename fails
    $count++;
}

答案 2 :(得分:0)

我终于找到了我正在寻找的东西。在Tim Peoples的回应的帮助下。最简单的回答是:

my $dirname = "../folder";
opendir (DIR, $dirname) or die "cannot open directory $dirname";
my @files = grep /[.]tif\z/, readdir DIR; #corrected pattern based on Sinan Ünür's comment
closedir (DIR);

my $basename = "file";
my $count = 1;
my $new;
foreach (@files) {
$new = "${basename}${count}.tif";
print "rename $_ $new\n";
rename ("$dirname/$_", "$dirname/$new") or warn "rename: $_: $new: $!\n"; #directory name     added to both the original file name and new file name. Thanks to Tim for helping me found this error using warn.
$count++;
}