Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl-帮助散列和转储记录_Perl_Multidimensional Array_Hash_Hash Of Hashes - Fatal编程技术网

perl-帮助散列和转储记录

perl-帮助散列和转储记录,perl,multidimensional-array,hash,hash-of-hashes,Perl,Multidimensional Array,Hash,Hash Of Hashes,我有一个perl脚本,它只保留命名集的最后一组记录,并且我有多个记录集。因此,它在散列中过度写入数据,只保留最后一个集。我需要帮助把所有记录打印出来。 谢谢 这是我的脚本副本: #!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my ($ServerName)=@ARGV; my %MyItems; foreach my $ServerName(@ARGV){ while (my $line = <

我有一个perl脚本,它只保留命名集的最后一组记录,并且我有多个记录集。因此,它在散列中过度写入数据,只保留最后一个集。我需要帮助把所有记录打印出来。 谢谢

这是我的脚本副本:

#!/usr/local/bin/perl 

use strict;
use warnings;
use Data::Dumper;

my ($ServerName)=@ARGV;
my %MyItems;
foreach my $ServerName(@ARGV){
   while (my $line = <>){
     chomp $line;
              if ($line =~ m/.* \w+ \d{2} (\d{2}:\d{2}:\d{2}) \d{4}: ([^:]+):backup:/){
                  my $ServerName = basename $ARGV, '.mydomain.com.backup-software.log'; #$ARGV is reading input from command line
                  my $BckupSet =$2;
                  my $BckupVal=$1;
                  $MyItems{$ServerName}{$BckupSet}->{'1-Server'}    = $ServerName;
                  $MyItems{$ServerName}{$BckupSet}->{'2-BackupSet'} = $BckupSet;
                  $MyItems{$ServerName}{$BckupSet}->{'3-StartTime'} = $BckupVal;

                  if ($line =~ m/(backup-date)[:=](.+)/){
                      my $BckupKey="4-DateStamp";
                      my $BckupVal=$2;
                      $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
                  }

                  if ($line =~ m/(backup-time)[:=](.+)/){
                      my $BckupKey="5-Duration";
                      my $BckupVal=$2;
                      $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
                  }
                  if ($line =~ m/(backup-size)[:=](.+)/){
                      my $BckupKey="6-Size";
                      my $BckupVal=$2;
                      $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
                  }
                  if ($line =~ m/(Backup succeeded)/){
                      my $BckupKey="7-Status";
                      my $BckupVal="Succeeded";
                      $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
                  }
                  if ($line =~ m/(ERROR)[:=](.+)/){
                      my $BckupKey="8-Status";
                      my $BckupVal="Unsuccessful";
                      $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
                      print "$BckupKey=$BckupVal\n" if debug;
                  }
              }
   } #endwhile
   print Dumper(\%MyItems);
   for my $ServerName(keys%MyItems){
     for my $BckupSet(keys%{$MyItems{$ServerName}}){
       for(sort keys%{$MyItems{$ServerName}{$BckupSet}}){
         #print$_,'=>',$MyItems{$ServerName}{$BckupSet}{$_},';';
         print$_,'=',$MyItems{$ServerName}{$BckupSet}{$_},';';
       }
       print"\n";
     }
   }
} #END foreach

根据调试输出,您的问题似乎在这里:

if ($line =~ m/(ERROR)[:=](.+)/){
    my $BckupKey="8-Status";
    my $BckupVal="Unsuccessful";
    $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
    print "$BckupKey=$BckupVal\n" if debug;
}
要保存所有错误,您需要将该哈希槽视为对数组的引用:

if ($line =~ m/(ERROR)[:=](.+)/){
    my $BckupKey="8-Status";
    my $BckupVal="Unsuccessful";
    push @{ $MyItems{$ServerName}{$BckupSet}{$BckupKey} } => $BckupVal;
    print "$BckupKey=$BckupVal\n" if debug;
}
在转储中,
8-Status
值类似于

'8-Status' => [ 'Unsuccessful', 'Other error', 'Et cetera' ], 要想得到第一个,你得写

print $MyItems{$ServerName}{$BckupSet}{$BckupKey}[0], "\n";
另一个问题是

foreach my $ServerName(@ARGV){
   while (my $line = <>){
然后,您需要首先从
@ARGV
中删除使用的服务器。区分用户打算作为服务器主机名的参数可能很棘手。一种惯例是使用
--
来表示选项处理的结束,因此您可以

my @servers;
while (@ARGV) {
  my $server = shift;
  last if $server eq "--"
  push @servers => $server;
}

die "Usage: $0 server .. -- log ..\n" unless @ARGV;

while (<>) {
  # ...
}
my@服务器;
while(@ARGV){
我的$server=shift;
最后一个if$server eq“-”
推送@servers=>$server;
}
除非@ARGV;
而(){
# ...
}

根据调试输出,您的问题似乎在这里:

if ($line =~ m/(ERROR)[:=](.+)/){
    my $BckupKey="8-Status";
    my $BckupVal="Unsuccessful";
    $MyItems{$ServerName}{$BckupSet}->{$BckupKey} = $BckupVal;
    print "$BckupKey=$BckupVal\n" if debug;
}
要保存所有错误,您需要将该哈希槽视为对数组的引用:

if ($line =~ m/(ERROR)[:=](.+)/){
    my $BckupKey="8-Status";
    my $BckupVal="Unsuccessful";
    push @{ $MyItems{$ServerName}{$BckupSet}{$BckupKey} } => $BckupVal;
    print "$BckupKey=$BckupVal\n" if debug;
}
在转储中,
8-Status
值类似于

'8-Status' => [ 'Unsuccessful', 'Other error', 'Et cetera' ], 要想得到第一个,你得写

print $MyItems{$ServerName}{$BckupSet}{$BckupKey}[0], "\n";
另一个问题是

foreach my $ServerName(@ARGV){
   while (my $line = <>){
然后,您需要首先从
@ARGV
中删除使用的服务器。区分用户打算作为服务器主机名的参数可能很棘手。一种惯例是使用
--
来表示选项处理的结束,因此您可以

my @servers;
while (@ARGV) {
  my $server = shift;
  last if $server eq "--"
  push @servers => $server;
}

die "Usage: $0 server .. -- log ..\n" unless @ARGV;

while (<>) {
  # ...
}
my@服务器;
while(@ARGV){
我的$server=shift;
最后一个if$server eq“-”
推送@servers=>$server;
}
除非@ARGV;
而(){
# ...
}

这是一个离题的话题,但每当您需要深度嵌套的数据结构时,您的代码都有可能变得臃肿和难以阅读。简单的便利性变量在简化事情和减轻代码读者(从现在起3个月后)的心理差异方面有很大的帮助:

# A convenience var.
my $bs = $MyItems{$ServerName}{$BckupSet};

# The rest of your code can use the var.
$bs->{'1-Server'} = $ServerName;
另外,您还有几个
if
块,它们基本上做相同的事情。似乎服从某种调度表策略:

my @dispatch_table = (
    {
        regex => qr/(backup-date)[:=](.+)/,
        key   => '4-DateStamp',
        val   => sub { $2 },
    },
    {
        # etc.
    },
);
然后,您的
if
块可以归结为如下内容:

for my $dt (@dispatch_table){
    next unless $line =~ $dt->{regex};
    $bs->{ $dt->{key} } = $dt->{val}->();
}

这是离题的,但每当您需要深度嵌套的数据结构时,您的代码都有可能变得臃肿和难以阅读。简单的便利性变量在简化事情和减轻代码读者(从现在起3个月后)的心理差异方面有很大的帮助:

# A convenience var.
my $bs = $MyItems{$ServerName}{$BckupSet};

# The rest of your code can use the var.
$bs->{'1-Server'} = $ServerName;
另外,您还有几个
if
块,它们基本上做相同的事情。似乎服从某种调度表策略:

my @dispatch_table = (
    {
        regex => qr/(backup-date)[:=](.+)/,
        key   => '4-DateStamp',
        val   => sub { $2 },
    },
    {
        # etc.
    },
);
然后,您的
if
块可以归结为如下内容:

for my $dt (@dispatch_table){
    next unless $line =~ $dt->{regex};
    $bs->{ $dt->{key} } = $dt->{val}->();
}

你到底希望看到什么?不止一台服务器?您希望看到什么?超过1台服务器?谢谢。我是否也会将推力应用于所有其他if条件?也要打印密钥吗?@jda6one9使用
push
对所有密钥都可以,但您可能会对单元素数组感到恼火。这样做的好处是永远不会丢弃数据,但对您想要做的事情来说可能过于宽松。您在前面帮助我使用-->xargs-I{}./myscript.pl{}谢谢。我是否也会将推力应用于所有其他if条件?也要打印密钥吗?@jda6one9使用
push
对所有密钥都可以,但您可能会对单元素数组感到恼火。这样做的好处是永远不会丢弃数据,但对您想要做的事情来说可能过于宽松。您在前面帮助我使用-->xargs-I{}./myscript.pl{}@FM-感谢您的提示!在过去的几周里,我基本上学会了perl。所以,我会尽我所能去学习。@FM-谢谢你的提示!在过去的几周里,我基本上学会了perl。所以,我会尽我所能去学习。