Добавление дополнительных функций в Perl-скрипт - PullRequest
0 голосов
/ 19 июля 2011

В приведенном ниже скрипте Perl я проверяю имя папки (в формате даты, например 11-08-31) с текущей датой. Если это совпадает, я обрабатываю папку. Он также проверяет папку предыдущего дня, если в текущей дате нет папки. Я уже задавал этот тип вопросов здесь, но мне нужно внести некоторые изменения здесь, а также добавить новые функции:

  • Скрипт проверяет предыдущую дату, если сегодняшние не найдены. Но мне нужно проверить, была ли предыдущая дата уже обработана или нет, чтобы я не обработал ее снова. Итак, мне нужно создать список для этого?

  • Этот скрипт проверяет только одну предыдущую дату. Что делать, если я должен проверить за 2 предыдущих дня? Спасибо за вашу помощь. надеюсь, вы понимаете мои сомнения.

Обновлено: этот Perl-скрипт запускается автоматически, когда проверяет текущую дату по имени папки. Папка является папкой tar, которая загружается с другого сервера.

Итак, мне нужно запустить скрипт, если он совпадает с именем папки и текущей датой.

Проблема: иногда я получал папку на следующий день, и мой Perl-скрипт проверял только текущую дату. Папка, которую я получаю, имеет имя, которое является предыдущей датой (не текущей датой). Итак, мне нужно сделать обработку папки вручную. Мне нужно автоматизировать это в моем Perl-скрипте


#!/usr/bin/perl
use strict;
use warnings;
use Cwd;
use DateTime;
use File::Copy;

# set to your desired time zone
my $today = DateTime->now( time_zone => "America/New_York" );
my $td = $today->strftime("%y-%m-%d");

# strongly recommended to do date math in the 'floating'/UTC zone
my $yesterday = $today->set_time_zone('floating')->subtract( days => 1);
my $yd = $yesterday->set_time_zone('America/New_York')->strftime("%y-%m-%d");

my $dir = shift or die "Provide path on command line. $!";

if ($dir eq '.') {
    $dir = cwd;
}
elsif ($dir !~ /^\//) {
    $dir = cwd() . "/$dir"; 
}

opendir my $dh, $dir or die $!;
my @dir = sort grep {-d and /$td/ || /$yd/} readdir $dh;
closedir $dh or die $!;
@dir or die "Found no date directories. $!";

my $dday = "$dir/$dir[-1]"; # is today unless today not found, then yesterday
my $fdir = '/some/example/path/';    
my @gzfiles = glob("$dday/*tar.gz");

foreach my $zf (@gzfiles) {  
    next if (($zf =~ /BMP/) || ($zf =~ /LG/) || ($zf =~ /MAP/) || ($zf =~ /STR/)); 
    print "$zf\n";
    copy($zf, $fdir) or die "Unable to copy. $!";
}

Ответы [ 3 ]

0 голосов
/ 20 июля 2011

Это решение находит все каталоги, которые еще должны быть обработаны, которые новее, чем самая последняя обработанная дата директории. Вы сделали запись вручную в первый раз (до запуска скрипта). Сценарий обновит его с этого момента.

Файл может быть назван как my $last = 'dir_last.dat'; Я только что ввел файл в командной строке, как:

C:\Old_Data\perlp>echo 11-07-14 > dir_last.bat

C:\Old_Data\perlp>type dir_last.bat
11-07-14

C:\Old_Data\perlp>

Предполагается, что самым новым каталогом был 11-07-14. Вы должны выяснить это сами, прежде чем запускать скрипт.

#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;

my $dir = shift or die "Provide path on command line. $!";

my $last = 'dir_last.dat';

open my $fh, "<", $last or die "Unable to open $last $!";
chomp(my $last_proc = <$fh>);
close $fh or die "Unable to close $last $!";

opendir my $dh, $dir or die "Opening failed for directory $dir $!";
my @dir = sort grep {-d && /^\d\d-\d\d-\d\d$/ && $_ gt $last_proc} readdir $dh;
closedir $dh or die "Unable to close $dir $!";
@dir or die "Found no date directories after last update: $last_proc";

my $fdir = '/some/example/path';

for my $date (@dir) {
    my $dday = "$dir/$date";
    my @gzfiles = glob("$dday/*tar.gz");

    foreach my $zf (@gzfiles) {  
        next if $zf =~ /BMP/ || $zf =~ /LG/ || $zf =~ /MAP/ || $zf =~ /STR/; 
        print "$zf\n";
        copy($zf, $fdir) or die "Unable to copy $zf to $fdir. $!";
    }
}

open  $fh, ">", $last or die "Unable to open $last $!";
print $fh "$dir[-1]\n"; # record the newest date-directory as processed
close $fh or die "Unable to close $last $!";

Обратите внимание, что я не полагался на cwd, как первый сценарий. Это действительно не было нужно там и не нужно здесь. opendir, glob и copy все могут обрабатывать каталог точек (cwd) и относительные пути.

Заголовок содержит строки use strict; и use warnings;. Их цель - предупредить вас об ошибках в вашем коде (большинство сценариев perl должны использовать их, если только эксперт не решит их исключить - по какой причине я не знаю). Первая строка сообщает unix, где найти интерпретатор (perl).

0 голосов
/ 21 июля 2011

Ну, еще один способ сделать это, как предлагает mugen kenichi , - использовать Storable.Таким образом сохраняется хэш со всеми обработанными каталогами.Затем, когда вы запускаете вашу программу, она может проверить хэш, чтобы увидеть, были ли они обработаны.

Вам потребуется одноразовый скрипт для настройки хэша обработанных каталогов.1007 * Затем периодически запускается скрипт для поиска и обработки ваших каталогов дат.

#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;
use Storable;

my $dir = shift or die "Provide path on command line. $!";

my $processed = retrieve('processed_dirs.dat'); # $processed is a hashref

opendir my $dh, $dir or die "Opening failed for directory $dir $!";
my @dir = grep {-d && /^\d\d-\d\d-\d\d$/ && !$processed->{$_} } readdir $dh;
closedir $dh or die "Unable to close $dir $!";
@dir or die "Found no unprocessed date directories";

my $fdir = '/some/example/path';

for my $date (@dir) {
    my $dday = "$dir/$date";
    my @gzfiles = glob("$dday/*tar.gz");

    foreach my $zf (@gzfiles) {  
        next if $zf =~ /BMP/ || $zf =~ /LG/ || $zf =~ /MAP/ || $zf =~ /STR/; 
        print "$zf\n";
        copy($zf, $fdir) or die "Unable to copy $zf to $fdir. $!";
    }
    $processed->{ $date } = 1;
}

store $processed, 'processed_dirs.dat';
0 голосов
/ 19 июля 2011

Если вы хотите сохранить статус обработки этих каталогов после одного запуска вашего приложения, вы можете создать файл .processed в каждом каталоге и проверить его существование перед обработкой каталога.

Если вам просто нужно сохранить состояние этих каталогов (обработано или необработано) во время выполнения вашего скрипта, вы можете использовать хеш-код с именем каталога:

my %PROCESSED = ();

if ($processing_done) {
  %PROCESSED{$dirname} = 1;
} else {
  %PROCESSED{$dirname} = 0;
}

чтобы узнать, обработан ли каждый каталог, считайте значение ключа из хеша:

if (%PROCESSED{$dirname} == 0) {
 ... do some processing
} else {
 ... this one is already done
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...