Как архивировать файлы .log с помощью Perl в Windows XP?

Как можно проще мне интересно, знает ли кто-нибудь, как архивировать файлы .log в каталоге Windows XP, просто назвав их текущим «localtime()» как часть имени файла? (Не предполагайте, что файл журнала заблокирован.) Я пробовал всевозможные способы сделать это, но не смог решить проблему... и в Интернете нет хороших примеров.

Вот что я ищу:

for (all files > that 1 day old)   
  rename file  to  file.[datestamp].log
end

person djangofan    schedule 22.04.2011    source источник
comment
Вы уверены, что у вас достаточно причин заново изобрести/повторно реализовать logrotate?   -  person abbot    schedule 22.04.2011
comment
Почему бы не использовать «logrotate»? Обычно предоставляется в большинстве дистрибутивов Linux или может быть скомпилирован из исходного кода при использовании системы nix, которая не предоставляет для нее пакет.   -  person ewh    schedule 22.04.2011
comment
есть ли двоичный файл для logrotate, который будет работать в Windows XP?   -  person djangofan    schedule 23.04.2011
comment
Ключевая проблема, с которой вы можете столкнуться, заключается в том, что файл может быть заблокирован, если он открыт в процессе, что препятствует успешному выполнению любой операции переименования. Если приложение не поддерживает внутреннюю ротацию журналов, вам потребуется остановить службу для ротации журналов. Кроме того, когда вы говорите, что не работает, пожалуйста, предоставьте подробную информацию о том, что на самом деле не работает в сценарии.   -  person ewh    schedule 23.04.2011
comment
Я попытался добавить примеры кода к этому вопросу, но все, что это сделало, это отвлекло людей от ответа на вопрос, поэтому я отредактировал свой пример кода.   -  person djangofan    schedule 04.05.2011


Ответы (3)


Ну, это выглядит так просто, я, наверное, что-то не понимаю. Задача переместить например "yada.log" в "yada.2011-05-04.log"? Тогда как насчет этого:

use strict;
use warnings;

use File::Copy;
use POSIX qw(strftime);

my $dir = $ARGV[0] or die "Usage: $0 <directory>";
my $now_string = strftime "%Y-%m-%d_%H%M%S", localtime;

opendir DIR, $dir or die $!;
my @files = readdir DIR;

chdir $dir or die $!;
for my $file (@files) {
    next if (-d $file);
    next unless ($file =~ /^(.*)(\.log)$/i);
    my $dst = $1 . "." . $now_string . $2;
    move ($file, $dst) or die "Failed to move $file: $!";
}
person TLP    schedule 04.05.2011
comment
Ваш скрипт работает для меня, но ему не нужно архивировать файлы, которые уже были заархивированы. Я не сказал этого в своем вопросе, но это то, что я имел в виду. - person djangofan; 04.05.2011
comment
Да, я только что подумал об этом некоторое время назад... next if ($file =~ /20\d{2}-\d{2}-\d{2}_\d{6}\.log$/i); должен это сделать (на ближайшие 89 лет). Во всяком случае, с этой датой. Боюсь, я не сделал ее очень красивой, только функциональной. - person TLP; 05.05.2011

Вот как я в конечном итоге это сделал, благодаря TLP! Этот скрипт содержит ошибки в строке №12, но он почти не работает.

use strict; 
use warnings;
use File::Copy; 
use POSIX qw(strftime); 

my $dir;
my $file;

if ( @ARGV = 2 ) { 
  print "Two args accepted."; 
  $dir = $ARGV[0] or die "Usage: <directory> <filename>";
  $file = $ARGV[1] or die "Usage: <directory> <filename>";
  goto runblock; 
}
else { print "Number of arguments must be 2: directory filename\n"; goto fail; }

runblock: print "Renaming $file .\n";

chdir $dir or die $!;
my $now_string = strftime "%Y-%m-%d_%H%M%S", localtime; 
if (-e $file) {
  if (-A $file > 7 ) {
    my $dst = "siteAlive." . $now_string . ".log"; 
    move($file, $dst) or die "Failed to move $file: $!";
    goto endscript;
  }
} 

fail: print "Failed to rename $file . Try again.\n" ;
endscript: print "End of script.\n";
person djangofan    schedule 04.05.2011
comment
if ( @ARGV = 2 ) вызывает небольшую ошибку. Вам нужно if ( @ARGV == 2 ), чтобы проверить значение, иначе вы присвоите ему новое значение. - person TLP; 05.05.2011
comment
Вы изменили некоторые вещи: вы не сохраняете частичное имя исходного файла (все они называются siteAlive), вы проверяете время доступа старше 7 дней вместо 1 и запускаете его для одного файла. Только. Я не уверен, что это сделано намеренно. Если вам нужна дополнительная помощь, дайте мне знать. - person TLP; 05.05.2011
comment
Спасибо. Да, я хотел получить ответ в целом, но я также хотел использовать то, что я узнал, в конкретном сценарии. - person djangofan; 09.05.2011

Возможно, есть некоторые модули, которые могут сделать это за вас, например, такие как Logfile::Rotate. .

person Joel Berger    schedule 07.05.2011