我必须在Perl中编写一个脚本,它将输出特定目录中的最后一个备份。
前者
父目录为/home/Backup/
在/home/Backup/windows
我有以下文件,例如
Windows_Server_A_20120901
Windows_Server_A_20120902
Windows_Server_A_20120903
Windows_Server_B_20120901
Windows_Server_B_20120902
Windows_Server_B_20120903
Windows_Server_XZ_20120903
Windows_Server_XZ_20120901
Windows_Server_XZ_20120902
Windows_Server_XZ_20120903
输出应为
Windows_Server_A_20120903
Windows_Server_B_20120903
Windows_Server_XZ_20120903
在/home/Backup/Unix
中,例如我有以下文件
Unix_Server_A_20120901.gz
Unix_Server_A_20120902.gz
Unix_Server_A_20120903.gz
Unix_Server_B_20120901.gz
Unix_Server_B_20120902.gz
Unix_Server_B_20120903.gz
Unix_Server_XY_20120901.gz
Unix_Server_XY_20120902.gz
Unix_Server_XY_20120903.gz
此输出应为
Unix_Server_A_20120903.gz
Unix_Server_B_20120903.gz
Unix_Server_XY_20120903.gz
我在这里举两个例子。在/home/Backup/
中,我有其他目录可以完成其他备份。
当然,对于每个子目录,都会有一个子程序,因为命名是不同的。
我是perl脚本编写的初学者。我们将非常感谢您的帮助。
从我的观点到目前为止我想要进行Windows备份。
有人可以指导我如何使用perl实现此目的。
谢谢大家。
我尝试在我要采取的最后一次备份
的步骤中更清楚一点Windows_Server_A(3次) Windows_Server_B(3次) Windows_Server_XY(3次)
当我指定路径时,我得到整个路径名,我该如何删除它
!/usr/bin/perl
use strict;
use warnings;
my @files = glob("Win*");
##my @files = glob("/home/backup/windows/Win*");
foreach my $file (@files) {
$file = substr($file,0,-9);
print "$file\n";
}
exit 0;
请您指导并告知我采取的步骤是否不好。
由于
答案 0 :(得分:1)
这不是关于“如何解决我的问题”的问题。如果你能证明你已经努力实际解决了这个问题并且你不仅仅使用stackoverflow作为一种免费的方式来完成你的工作,那将是很好的。
我建议您先阅读本书Learning Perl和/或查看:
*编辑此处编辑,因为代码的注释有点受限:
我不确定重复是什么意思。 glob ("path/to/files*")
将为每个匹配的文件返回一个条目。为您的数据建立合适的结构的一种方法是:
use strict;
use warnings;
use Data::Dumper;
my ($win, $unix);
foreach my $dir (qw#/first/path/files /second/path/to/files /and/more/paths#) {
foreach my $file (glob ("$dir/*")) {
$file =~ s/$dir\///; # the file will contain the dir here, remove that + /
$file =~ /^([A-Za-z_]*?)_([A-Z]+)_(\d+)(\.gz)?$/; # match the file
my ($type, $weird_letter, $date, $is_unix);
if ($1) {
($type, $weird_letter, $date, $is_unix) = ($1, $2, $3, $4);
} else {
print STDERR "$file doesn't match, skipping!\n";
next;
}
if ($is_unix) { # if it's a .gz file is it "unix", otherwise windows.
$unix->{$dir}{$weird_letter}{$date} = $file;
} else {
$win->{$dir}{$weird_letter}{$date} = $file;
}
}
}
print Dumper ($win, $unix);
这个解决方案有点天真,例如,如果你有大量的文件,最好是在* AZ *类型上使用readdir或匹配,并且一次取一个。这里留下的是使用sort函数并只打印相关文件。
如果你展示了更多你自己尝试过的东西,那么你就更有可能得到帮助,因为很多人来到像stackoverflow这样的地方有工作/学校问题而只是希望解决方案而不做任何工作。
答案 1 :(得分:0)
你可能想尝试这样的事情,只需使用@files
或readdir
填充glob
来自dir的相关文件:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my @files = qw(Windows_Server_A_20120901
Windows_Server_A_20120902
Windows_Server_A_20120903
Windows_Server_B_20120901
Windows_Server_B_20120902
Windows_Server_B_20120903
Windows_Server_XZ_20120903
Windows_Server_XZ_20120901
Windows_Server_XZ_20120902
Windows_Server_XZ_20120903);
my %seen;
my %latest = map { $_->[0] => $_->[1] }
grep { not $seen{$_->[0]}++ }
sort { $b->[1] <=> $a->[1] }
map { my ($server,$time) = $_ =~ m/^(.+?)_(\d+)$/;
[$server, $time] } @files;
print Dumper(\%latest);
答案 2 :(得分:0)
这应该做你需要的。它查找/home/Backup/
中的所有目录,在每个目录中查找最新日期的文件,并显示所有具有dame日期的文件
use strict;
use warnings;
use File::Spec;
my $root = '/home/Backup/';
opendir my $dh, $root or die $!;
my @dirs;
while (readdir $dh) {
next if /^\.\.?$/;
my $dir = File::Spec->catdir($root, $_);
next unless -d $dir;
push @dirs, $dir;
}
for my $dir (@dirs) {
print "\nProcessing directory $dir\n";
opendir my $dh, $dir or die $!;
my @files;
my $lastdate = 0;
while (readdir $dh) {
my $file = File::Spec->catfile($root, $_);
next unless -f $file;
next unless /\D(\d{8})(\.|$)/;
$lastdate = $1 if $1 > $lastdate;
push @files, $file;
}
print "$_\n" for grep /\D$lastdate(?:\.|$)/, @files;
}