2010-03-31 104 views
3

可能重复: Renaming and Moving Files in Bash or Perl如何检查文件是否存在,并在Perl重命名

我有点新手,Perl和寻找一个脚本,将处理的文件移动。

#!/usr/bin/perl -w 
$filename = 'DUMBFILE'; 
$destination = '/some/location/'; 
if (-e $destination + $filename) { 
    print "File Exists ! Renaming .."; 
    move ('/tmp/' + $filename, $destination + $filename + '.1'); 
} else { 
    move ('/tmp/' + $filename, $destination + $filename); 
} 

我能够将其重命名为1,但我不想被逐步改名,就像如果file.1的存在,重命名为.2和.3如果0.2存在。

编辑:并保持扩展相同;喜欢的file.exe变得file.exe.1,file.exe.2等

+5

字符串连接使用'.'不'+'来实现的。您最好使用'Path :: Class'或'File :: Spec'来形成单个组件的路径。最后,你的脚本的逻辑不清楚。你似乎用'/ tmp/DUMBFILE'来覆盖'/ some/location/DUMBFILE.1'。 – 2010-03-31 14:13:46

+0

这是http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919的副本。 (在主题中忽略“bash” - OP说perl很好) - 接受的答案提供了移动脚本 – DVK 2010-03-31 17:07:18

回答

3
#!/usr/bin/perl 
use strict; 
use warnings; 

use File::Spec::Functions qw'catfile'; 
use File::Copy qw'move'; 
use autodie qw'move'; 

my $filename = 'DUMBFILE'; 
my $origin  = '/tmp'; 
my $destination = '/some/location'; 

my $path = catfile $destination, $filename; 
{ 
    my $counter; 
    while(-e $path){ 
    $counter++; 
    $path = catfile $destination, "$filename.$counter"; 
    } 
} 

move(catfile($origin, $filename), $path); 
+0

与扩展保持一致吗? (见我的其他评论) – Disco 2010-03-31 15:14:20

+0

@Disco,也许你应该编辑你的问题。 – 2010-03-31 15:31:41

+0

http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919有扩展保留的答案 – DVK 2010-03-31 17:08:25

4

你需要级联.,而不是+

if (-e $destination . $filename) { 

,甚至更好。您可以使用File::Spec模块:

use File::Spec; 
... 
if (-e File::Spec->join($destination, $filename)) { 

并请use strict;

要移动的文件,你可以使用File::Copy模块:

use File::Copy; 
... 
move($from, $to); 
+0

这仍然没有解决问题的核心部分 - 追加到名称的增量计数器。 – Cascabel 2010-03-31 14:24:14

4

也许你想要做的是一样的东西:

use File::Copy; 

sub construct_filename { 
    my ($dir, $name, $counter) = @_; 
    if ($name =~ /^(.*)\.(.*)$/) { 
     return "$dir/$1.$counter.$2"; 
    } else { 
     return "$dir/$name.$counter"; 
    } 
} 

if (-e "$destination$filename") { 
    $counter = 1; 
    while (-e construct_filename($destination,$filename,$counter)) { 
     $counter++; 
    } 
    move("/tmp/$filename", construct_filename($destination,$filename,$counter)); 
} else { 
    move("/tmp/$filename", "$destination$filename"); 
} 

另外,字符串连接o perl中的perator是.,而不是+。你写的东西根本不起作用。在这种情况下,尽管可以使用双引号字符串插值,但并不打扰拼接。

而且值得一提的是,一个更简单的约定是目录永远不会包含尾随斜线,并且在构造文件名时总是使用它们(例如"$destination/$filename")。正如其他人指出的那样,建立路径的最可靠方法是File::Spec。然而,从我可以告诉的是,你真正想要的部分是如何进行增量命名;所以我给出了一个清晰简短的版本。如你所见,升级至File::Spec!在Perl

+3

检查$ filename。$ counter并使用它有一个竞争条件。这可能永远不会成为问题,但值得了解。 – 2010-03-31 14:19:20

+0

@Josh Kelley:谢谢,我想提一下,但我完成时忘了。 – Cascabel 2010-03-31 14:23:53

+0

谢谢,它的工作......但现在我看到,我不想将文件重命名为.1,而是保留扩展名。 像'file.exe'重命名为'file.1.exe''file.2.exe'等... – Disco 2010-03-31 15:09:02

2
#!/usr/bin/perl -w 
$filename = 'DUMBFILE'; 
$destination = '/some/location/'; 
$filepath=$destination.$filename; 
if (-e $filepath) { 
    print "File Exists ! Renaming .."; 
    $counter++; 
    rename('/tmp/'.$filename.$filepath.$counter); 
} else { 
    move ('/tmp/'.$filename.$filepath); 
} 
相关问题