Perl do while循环中出现问题
这是剧本Perl do while循环中出现问题,perl,Perl,这是剧本 #!/usr/bin/perl use strict; use warnings; my($dayago, $prefix, $today_timestamp, $f, $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $daysago, $now, $old, @oldbackup); opendir(DIR, "/home/ftpusr/backup/") || die("Error canno
#!/usr/bin/perl
use strict;
use warnings;
my($dayago, $prefix, $today_timestamp, $f,
$sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst,
$daysago, $now, $old, @oldbackup);
opendir(DIR, "/home/ftpusr/backup/") || die("Error cannot open directory");
$now = time();
$dayago = 3;
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now-$dayago*60*60*24);
#$today_timestamp=sprintf("%4d%02d%02d",$year+1900,$mon+1,$mday);
#$old_timestamp=
$prefix = ".CATN0000.";
do {
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
= localtime($now - $dayago * 60 * 60 * 24);
$today_timestamp = sprintf("%4d%02d%02d", $year + 1900, $mon + 1, $mday);
while ($f = readdir(DIR)){
if ( $f =~ /$prefix$today_timestamp/ ) {
print "$f\n";
}
}
$dayago -= 1;
print "$dayago\n";
print "$today_timestamp\n";
} until ($dayago == 0);
closedir(DIR);
这是目录中的文件
-rw-r----- 1 db2inst1 db2grp1 184569856 2013-03-13 10:24 GSRTC.0.db2inst1.NODE0000.CATN0000.20130313102253.001
-rwxr-xr-x 1 db2inst1 db2grp1 259 2013-03-13 13:00 space_check.sh
-rw-r----- 1 db2inst1 db2grp1 1071665152 2013-03-14 10:06 AWDRT.0.db2inst1.NODE0000.CATN0000.20130314095856.001
-rw-r----- 1 db2inst1 db2grp1 184569856 2013-03-14 10:20 GSRTC.0.db2inst1.NODE0000.CATN0000.20130314101854.001
-rw-r--r-- 1 db2inst1 db2grp1 0 2013-03-14 13:49 bkp.sh
-rwxrwxrwx 1 db2inst1 db2grp1 1070 2013-03-14 20:12 awdrt_tabspc_report.sh
-rw-r----- 1 db2inst1 db2grp1 1085296640 2013-03-15 10:11 AWDRT.0.db2inst1.NODE0000.CATN0000.20130315100434.001
-rw-r----- 1 db2inst1 db2grp1 184569856 2013-03-15 10:30 GSRTC.0.db2inst1.NODE0000.CATN0000.20130315102900.001
-rw-r----- 1 db2inst1 db2grp1 1075859456 2013-03-16 12:16 AWDRT.0.db2inst1.NODE0000.CATN0000.20130316121043.001
运行脚本时,输出为:
GSRTC.0.db2inst1.NODE0000.CATN0000.20130313102253.001
2
20130313
1
20130314
0
20130315
相反,我想要这些文件:
-rw-r----- 1 db2inst1 db2grp1 1071665152 2013-03-14 10:06 AWDRT.0.db2inst1.NODE0000.CATN0000.20130314095856.001
-rw-r----- 1 db2inst1 db2grp1 184569856 2013-03-14 10:20 GSRTC.0.db2inst1.NODE0000.CATN0000.20130314101854.001
-rw-r----- 1 db2inst1 db2grp1 1085296640 2013-03-15 10:11 AWDRT.0.db2inst1.NODE0000.CATN0000.20130315100434.001
-rw-r----- 1 db2inst1 db2grp1 184569856 2013-03-15 10:30 GSRTC.0.db2inst1.NODE0000.CATN0000.20130315102900.001
我想要的是它应该保留最后一个文件并删除旧的备份。
非常感谢您的帮助。这一个对我有用
#!/usr/bin/perl
use strict;
use warnings;
my($dayago,$prefix,$today_timestamp,$f,$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$daysago,$now,$old,@oldbackup);
#opendir(DIR, "/home/ftpusr/backup/") || die("Error cannot open directory");
$now=time();
$dayago=3;
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now-$dayago*60*60*24);
#$today_timestamp=sprintf("%4d%02d%02d",$year+1900,$mon+1,$mday);
#$old_timestamp=
$prefix = ".CATN0000.";
do {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($now-$dayago*60*60*24);
opendir(DIR, "/home/ftpusr/backup/") || die("Error cannot open directory");
$today_timestamp=sprintf("%4d%02d%02d",$year+1900,$mon+1,$mday);
while ($f = readdir(DIR)){
if ( $f =~ /$prefix$today_timestamp/ ) {
print "$f\n";
}
}
$dayago -= 1;
print "$dayago\n";
print "$today_timestamp\n";
}until ($dayago == 0);
closedir(DIR);
有更好的解决方案吗?????我不太清楚您想做什么,但它与在名称中嵌入的日期之前对文件进行排序(并可能删除?尽管您没有删除任何内容)有关。首先让我指出一个模块,它允许您从
localtime
获取信息,但存储在方便的对象中的信息除外。此外,您还可以使用从格式化时间创建它们
在下面的脚本中,我创建了一个数组引用数组,与模式匹配的每个文件对应一个数组引用。arrayref的第一个元素是文件名,第二个元素是从名称中日期字符串的前8位创建的Time::Piece
对象。我还创建了一个表示now的对象
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $now = localtime();
my $prefix = "CATN0000";
opendir(my $dir, "/home/ftpusr/backup/") || die("Error cannot open directory: $!");
my @files;
while ( my $file = readdir $dir ) {
$file =~ /\.$prefix\.(\d{8})\d*\.\d{3}/ or next;
push @files, [ $file, Time::Piece->strptime( $1, '%Y%m%d') ];
}
从这个起点开始,您可以通过比较Time::Piece
对象进行排序,将它们与$now
对象进行比较,然后根据需要对文件执行任何操作
readdir
函数将返回该目录中的所有项目。在标量上下文中使用,它返回下一个条目,如果没有其他可用项,则返回undef
。这使它成为一个迭代器。要重置迭代器,必须重新打开目录。最好将所有项读入一个数组,然后选择与特定模式匹配的项
是元字符,默认情况下与任何非换行符匹配。要匹配文字点,必须将其转义,或将其括在\Q..\E
引号中$days\u之前给定的时间戳的子组件:
正在读取目录中的所有文件:
这将使用do
块。词法文件或目录句柄一旦超出范围就会自动关闭。变量$代码>包含失败的原因
选择所有匹配的文件:
这需要几天前的时间,以及对我们的文件数组的引用。正则表达式上的/x
修饰符允许我们包含不匹配的空白,以便更好地格式化。可以像my@interest=matching\u files(7,\@files)
(请参阅参考运算符\
)
获取和打印两天前的所有文件
范围操作符。
创建序列0,1,2
,我们将其反转。类似于for
的循环结构可以显示为尾部语句修饰符。内部的foreach
将把每个项目放入$\u
标题应反映问题的内容。对不起。。。。。。。。。请不要修改,以便更清楚地说明您想要做什么。最后一句话是一个开始,但我仍然不能理解它的头绪。
{ # begin a enclosing scope for private variable
my $now = time;
my $secs_per_day = 24 * 60 * 60;
sub timestamp {
my ($ago) = @_;
# we can use `undef` for vars we don't use
my (undef, undef, undef, $mday, $mon, $year)
= localtime( $now - $ago * $secs_per_year);
return sprintf '%04d%02d%02d', $year + 1900, $mon + 1, $mday;
}
}
my $directory = '/foo/bar';
my @files = do {
opendir my $dir, $directory or die "Can't open $directory: $!";
readdir $dir;
};
sub matching_files {
my ($days_ago, $files) = @_;
my $timestamp = timestamp($days_ago)
return grep /\Q .CATN0000. $timestamp \E/x, @$files;
}
for my $days_ago (reverse 0 .. 2) {
my @interesting = matching_files($days_ago, \@files);
print "Days ago: $days_ago\n";
print "$_\n" foreach @interesting;
}