在perl脚本中添加更多功能

在perl脚本中添加更多功能,perl,Perl,在下面的perl脚本中,我用当前日期检查我的文件夹名(日期格式为11-08-31)。如果匹配,我将处理该文件夹。如果今天的日期中没有文件夹,它还会检查前一天的文件夹。我已经在这里问过这类问题,但我需要在这里做一些更改,并添加新功能: 如果找不到今天,脚本将检查上一个日期。但是我需要检查前一个日期是否已经被处理过,这样我就不会再处理它了。那么,我需要为它创建一个列表吗 此脚本仅检查前一个日期。如果我必须检查前两天的情况呢?谢谢你的帮助。希望你能理解我的疑惑 更新:此perl脚本在检查当前日期和

在下面的perl脚本中,我用当前日期检查我的文件夹名(日期格式为11-08-31)。如果匹配,我将处理该文件夹。如果今天的日期中没有文件夹,它还会检查前一天的文件夹。我已经在这里问过这类问题,但我需要在这里做一些更改,并添加新功能:

  • 如果找不到今天,脚本将检查上一个日期。但是我需要检查前一个日期是否已经被处理过,这样我就不会再处理它了。那么,我需要为它创建一个列表吗

  • 此脚本仅检查前一个日期。如果我必须检查前两天的情况呢?谢谢你的帮助。希望你能理解我的疑惑

更新:此perl脚本在检查当前日期和文件夹名称时自动运行。该文件夹是从其他服务器加载的tar文件夹

因此,基本上我需要运行脚本,如果它与文件夹名称和当前日期匹配

问题:有时,我习惯于第二天获取文件夹,而我的perl脚本只检查当前日期。我得到的文件夹的名称是前一个日期(不是当前日期)。因此,我需要手动处理该文件夹。我需要在perl脚本中实现自动化



如果要在应用程序的一次运行之后保持这些目录是否已被处理的状态,可以在每个目录中创建一个.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
}

此解决方案将查找比最近处理的目录日期更新的所有尚未处理的目录。第一次(在脚本运行之前)手动记录。脚本将从此点开始更新它

该文件可以命名为
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 $!";
#/usr/bin/perl
严格使用;
使用警告;
使用文件::复制;
my$dir=shift或die“在命令行上提供路径。$!”;
my$last='dir_last.dat';
打开我的$fh,“,$last”或“无法打开$last$!”;
打印$fh“$dir[-1]\n”#记录已处理的最新日期目录
关闭$fh或死亡“无法关闭$last$!”;
注意,我不像第一个脚本那样依赖于
cwd
。那里真的不需要,这里也不需要
opendir
glob
copy
都可以处理点(cwd)目录和相对路径


标题包括行
use strict
使用警告。它们的目的是提醒您代码中的错误(大多数perl脚本都应该使用它们,除非专家决定排除它们——我不知道原因是什么)。第一行告诉unix在哪里可以找到解释器(perl)。

好的,另一种方法是使用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';

你为什么不抓取最新的可用文件夹并处理它呢?如果我没有弄错的话,这似乎就是你正在尝试的。你可以另外检查它的年龄是否在特定的天数范围内。我想自动完成。我从其他站点获取目录中的文件夹,然后我需要处理它。但有时,文件夹会延迟一天到达。所以,我还需要检查上一个日期。请检查问题中更新的部分。但您仍然只想处理最新的未处理文件夹?要在脚本运行之间跟踪已处理的文件夹,可以使用纯文本文件或可存储的Yes。我需要处理最新的文件夹。但有时,您在一天内得到两个文件夹,然后您需要同时处理这两个文件夹。因此,我还需要通过将上一个日期与文件夹名称匹配来检查这些文件夹。在我的脚本中,我只检查今天的文件夹,如果它不存在,我检查上一个日期。我需要在我的脚本中强制检查这两个文件夹,看看前一个日期文件夹是否被处理。嗨,我有一些疑问。我知道我最近处理过的文件夹,因为我可以在处理过的文件夹列表中看到它。但是我如何手动放置它呢?比如11-04-21是最新的文件夹,那么在脚本中,我应该在哪里使用它来代替什么呢?在您的例子中,11-07-14是最新处理的文件夹,那么您在脚本中使用它的位置是什么?在上面,我创建了
dir_last.dat
文件,其中包含:
echo 11-07-14>dir_last.bat',只需将其更改为:
echo 11-04-21>dir_last.bat`此命令是在您的命令行输入的。这样只需创建一次文件。脚本将在代码中保持最新。令人惊讶的东西…但我想,它仍然有一些问题。假设您在同一日期得到两个文件夹。一个文件夹应该在前一天到达,第二个文件夹应该在同一天到达。因此,如果它首先处理第二个文件夹,dir_last.dat将用新日期更新。第一个文件夹永远不会被处理,因为它的日期比新的要短。基本上,我得到的文件夹应该来得早一点,但它们不会在指定的时间到达。它们在下一个日期(当前日期)与另一个文件夹一起到达。所以,我需要检查所有我需要的文件夹。e当前日期和以前日期文件夹(i
#!/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';