Исходя из результатов отладки, похоже, что ваша проблема здесь:
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' ],
Если вы захотите зациклить их позже, вы сделаете что-то вроде
foreach my $err (@{ $MyItems{$ServerName}{$BckupSet}{$BckupKey} }) {
print "got $err\n";
}
Чтобы получить только первое, вы должны написать
print $MyItems{$ServerName}{$BckupSet}{$BckupKey}[0], "\n";
Другая проблема:
foreach my $ServerName(@ARGV){
while (my $line = <>){
Поймите, что while (<>) { ... }
неявно зацикливается на всех файлах, названных в @ARGV
, поэтому вложите еговнутри цикла над @ARGV
не совсем имеет смысла.Если ваша командная строка имеет вид
$ readlogs server1 server2 server3 log1 log2
, то вам нужно сначала удалить с @ARGV
серверы, используя shift
.Отличительные аргументы, которые пользователь намеревается использовать в качестве имен хостов сервера, могут быть хитрыми.Согласно одному соглашению --
сигнализирует об окончании обработки опций, поэтому вы можете
my @servers;
while (@ARGV) {
my $server = shift;
last if $server eq "--"
push @servers => $server;
}
die "Usage: $0 server .. -- log ..\n" unless @ARGV;
while (<>) {
# ...
}