在下面的perl脚本中,我用当前日期检查我的文件夹名称(日期格式如11-08-31)。如果匹配,我处理该文件夹。如果今天的日期没有文件夹,它还会检查前一天的文件夹。我已经在这里提出了这类问题,但我需要在这里进行一些更改并添加新功能:
如果今天找不到,脚本会检查上一个日期。但我需要检查之前的日期是否已经处理过,以便我不再处理它。那么,我是否需要为它创建一个列表?
此脚本仅检查上一个日期。如果我必须检查前两天怎么办?谢谢你的帮助。希望你理解我的疑惑。
更新:此perl脚本在使用文件夹名称检查curent日期时自动运行。该文件夹是一个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. $!";
}
答案 0 :(得分:0)
如果要保持这些目录是否在应用程序的单次运行之后处理的状态,您可以在每个目录中创建一个.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
}
答案 1 :(得分:0)
此解决方案查找尚未处理的所有目录,这些目录比最近处理的目标日期更新。您已经第一次手动记录它(在脚本运行之前)。该脚本将从该点开始更新。
该文件可以命名为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)。
答案 2 :(得分:0)
嗯,正如mugen kenichi所建议的那样,另一种方法是使用Storable。这种方式存储包含所有已处理目录的哈希。然后,当您运行程序时,它可以检查哈希以查看它们是否已被处理。
您需要一次性脚本来设置已处理目录的哈希值。
#!/usr/bin/perl
use strict;
use warnings;
use Storable;
# This script to be run 1 time only. Sets up 'processed' directories hash.
# After this script is run, ready to run the daily script.
my $dir = '.'; # or what ever directory the date-directories are stored in
opendir my $dh, $dir or die "Opening failed for directory $dir $!";
my @dir = grep {-d && /^\d\d-\d\d-\d\d$/ && $_ le '11-04-21'} readdir $dh;
closedir $dh or die "Unable to close $dir $!";
my %processed = map {$_ => 1} @dir;
store \%processed, 'processed_dirs.dat';
然后,定期运行脚本以查找和处理日期目录。
#!/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';