2010-03-31 2 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, и 0,3, если 0,2 существует.

РЕДАКТИРОВАТЬ: и сохранить расширение одинаково; как file.exe становится file.exe.1, file.exe.2 и т.д.

+5

Объединение строк в Perl достигается с помощью '' .' не + '. Вам лучше использовать «Path :: Class» или «File :: Spec» для формирования путей от отдельных компонентов. Наконец, логика вашего сценария не ясна. Кажется, вы переписываете '/ some/location/DUMBFILE.1' с'/tmp/DUMBFILE'. –

+0

Это дубликат http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919. (игнорируйте «bash» в теме - OP сказал, что perl был в порядке) - принятый ответ предоставляет сценарий для перемещения – DVK

ответ

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

+0

@ Disco, возможно, вы должны отредактировать свой вопрос. –

+0

http://stackoverflow.com/questions/2548835/renaming-and-moving-files-in-bash-or-perl/2548919#2548919 имеет ответ с расширением – DVK

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

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 perator в perl: ., а не +. То, что вы написали, не будет работать вообще. В этом случае вы можете просто использовать интерполяцию строк с двойными кавычками, хотя и не беспокоиться о конкатенации.

И для того, что стоит, более простое соглашение состоит в том, чтобы каталоги никогда не содержали конечные косые черты и всегда использовали их при создании имен файлов (например, "$destination/$filename"). Как указывали другие, наиболее надежный способ создания пути - File::Spec. Из того, что я мог сказать, часть, которую вы действительно искали, заключалась в том, как делать инкрементное именование; поэтому я дал четкую и короткую версию этого. Обновите до File::Spec, как вы сочтете нужным!

+3

Существует условие гонки между проверкой $ filename $ counter и использованием. Это, вероятно, никогда не будет проблемой, но стоит знать. –

+0

@ Josh Kelley: Спасибо, я хотел упомянуть об этом, но забыл к тому времени, когда я закончил. – Cascabel

+0

Спасибо, он работает ... но теперь я вижу, что я не хочу переименовывать файл в .1, но вместо этого сохранить расширение. Как с «file.exe» переименовать в «file.1.exe» «file.2.exe» и т. Д. – Disco

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); 
} 
Смежные вопросы