使用Perl查找目录中的最后备份文件

时间:2012-09-16 07:34:30

标签: perl

我必须在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备份。

  1. strip(_20120901),即文件名
  2. 中的最后9个字符
  3. 然后搜索lastbackup。
  4. 有人可以指导我如何使用perl实现此目的。

    谢谢大家。

    我尝试在我要采取的最后一次备份

    的步骤中更清楚一点
    1. 恢复数组中服务器的唯一名称
    2. 然后使用名称(ls | grep Windows_A | head -1)获取最新备份
    3. 我将更改目录。我不会读取/ home / backup
    4. 中的所有文件夹
    5. 我也没有大量文件
    6. 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;
      

      请您指导并告知我采取的步骤是否不好。

      由于

3 个答案:

答案 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)

你可能想尝试这样的事情,只需使用@filesreaddir填充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;
}