2010-08-20 6 views
1

J'ai un script Perl qui ne conserve que le dernier ensemble d'enregistrements pour un ensemble nommé et j'ai plus d'un ensemble d'enregistrements. Donc c'est fini d'écrire les données dans le hachage et de garder le dernier ensemble. J'ai besoin d'aide pour imprimer tous les dossiers. Merci!perl - aide au hachage et au vidage des enregistrements

Voici une copie de mon script:

#!/usr/local/bin/perl 

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

my ($ServerName)[email protected]; 
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 

Voici à quoi il ressemble quand il dépotoirs:

$VAR1 = { 
      'server1.name.colo' => { 
             'set1' => { 
                   '3-StartTime' => '07:08:15', 
                   '1-Server' => 'server1.name.colo', 
                   '6-Size' => '72.04 GB', 
                   '7-Status' => 'Succeeded', 
                   '4-DateStamp' => '20100820060002', 
                   '5-Duration' => '01:08:13', 
                   '2-BackupSet' => 'set1', 
                   '8-Status' => 'Unsuccessful' 
                  }, 
             'set2' => { 
                   '7-Status' => 'Succeeded', 
                   '6-Size' => '187.24 GB', 
                   '3-StartTime' => '01:51:25', 
                   '4-DateStamp' => '20100820000003', 
                   '1-Server' => 'server1.name.colo', 
                   '5-Duration' => '01:51:21', 
                   '2-BackupSet' => 'set2' 
                   }, 
             'set3' => { 
                   '3-StartTime' => '23:00:05', 
                   '4-DateStamp' => '20100814230003', 
                   '1-Server' => 'server1.name.colo', 
                   '8-Status' => 'Unsuccessful', 
                   '2-BackupSet' => 'set3' 
                  }, 
             'set4' => { 
                   '7-Status' => 'Succeeded', 
                   '6-Size' => '427.75 GB', 
                   '3-StartTime' => '00:43:20', 
                   '4-DateStamp' => '20100819200004', 
                   '1-Server' => 'server1.name.colo', 
                   '5-Duration' => '04:43:14', 
                   '2-BackupSet' => 'set4' 
                  }, 
             'set3' => { 
                   '7-Status' => 'Succeeded', 
                   '6-Size' => '46.42 GB', 
                   '3-StartTime' => '04:42:59', 
                   '4-DateStamp' => '20100820040002', 
                   '1-Server' => 'server1.name.colo', 
                   '5-Duration' => '00:42:56', 
                   '2-BackupSet' => 'set3' 
                  } 
             } 
     }; 
+0

qu'attendez-vous pour voir exactement? plus de 1 serveur? – cam

Répondre

2

Basé sur la sortie de débogage, il ressemble à votre problème est ici:

Pour enregistrer toutes les erreurs, vous devez traiter ce logement de hachage comme une référence à un tableau:Pour enregistrer toutes les erreurs, vous devez traiter ce logement de hachage comme une référence à un groupe:
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; 
} 

Dans votre décharge, les valeurs 8-Status ressembleront

'8-Status' => [ 'Unsuccessful', 'Other error', 'Et cetera' ],

Si vous voulez faire une boucle sur eux plus tard, vous feriez quelque chose comme

foreach my $err (@{ $MyItems{$ServerName}{$BckupSet}{$BckupKey} }) { 
    print "got $err\n"; 
} 

Pour que le premier , vous écririez

print $MyItems{$ServerName}{$BckupSet}{$BckupKey}[0], "\n"; 

Une autre question est

foreach my $ServerName(@ARGV){ 
    while (my $line = <>){ 

Sachez que while (<>) { ... } boucles implicitement sur tous les fichiers nommés dans @ARGV, il imbrication donc dans une boucle sur @ARGV ne fait pas tout à fait sens. Si votre ligne de commande est de la forme

$ readlogs server1 server2 server3 log1 log2

alors vous voulez d'abord supprimer de @ARGV les serveurs à l'aide shift. Les arguments distinctifs que l'utilisateur a l'intention d'utiliser comme noms d'hôte du serveur peuvent être difficiles. Une convention utilise -- pour signaler la fin du traitement des options, vous pourriez donc

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

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

while (<>) { 
    # ... 
} 
+0

merci. est-ce que j'appliquerais la poussée à tous mes autres si les conditions aussi bien? imprimer les clés aussi? – jdamae

+0

@ jda6one9 L'utilisation de 'push' pour chacun d'entre eux fonctionnerait, mais vous risquez d'être ennuyé avec des tableaux à un seul élément. Le faire de cette façon a l'avantage de ne jamais jeter de données, mais cela peut être trop permissif pour ce que vous voulez faire. –

+0

vous m'a aidé plus tôt en utilisant ce -> xargs -I {} ./myscript.pl {} jdamae

2

Ceci est hors sujet, mais chaque fois que vous avez besoin des structures de données profondément imbriquées votre code court un risque de devenir pléthorique et difficile à lire. Les variables simples de commodité vont un long chemin vers la rationalisation des choses et de soulager le lecteur du code (vous, 3 mois à partir de maintenant) d'avoir à effectuer de nombreuses diffs mentales:

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

# The rest of your code can use the var. 
$bs->{'1-Server'} = $ServerName; 

, vous avez également plusieurs if blocs faire essentiellement la même chose. Il semble prête à une sorte de stratégie de table d'expédition:

my @dispatch_table = (
    { 
     regex => qr/(backup-date)[:=](.+)/, 
     key => '4-DateStamp', 
     val => sub { $2 }, 
    }, 
    { 
     # etc. 
    }, 
); 

Ensuite, vos if blocs se résument à quelque chose comme ceci:

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

@FM - merci pour les conseils! J'ai essentiellement appris perl au cours des dernières semaines. Donc, je vais prendre ce que je peux obtenir aussi loin que l'apprentissage. – jdamae