chickenman has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,
i need your help. I am trying to parse the following output.

Configuration - DGCONF Protection Mode: MaxAvailability Databases: DB1 - Primary database DB2 - Physical standby database Properties: FastStartFailoverThreshold = '30' OperationTimeout = '30' FastStartFailoverLagLimit = '30' CommunicationTimeout = '180' ObserverReconnect = '0' FastStartFailoverAutoReinstate = 'TRUE' FastStartFailoverPmyShutdown = 'TRUE' BystandersFollowRoleChange = 'ALL' ObserverOverride = 'FALSE' ExternalDestination1 = '' ExternalDestination2 = '' PrimaryLostWriteAction = 'CONTINUE' Fast-Start Failover: DISABLED Configuration Status: SUCCESS
As a result i need a hash like this
$VAR2 = { 'Configuration' => 'DGCONF', 'ProtectionMode' => 'MaxAvailability', 'Databases' => { 'DB1' => 'Primarydatabase', 'DB2' => 'Physicalstandbydatabase' }, 'Properties' => { 'ExternalDestination2' => '', 'FastStartFailoverThreshold' => '30', 'ObserverReconnect' => '0', 'ObserverOverride' => 'FALSE', 'OperationTimeout' => '30', 'PrimaryLostWriteAction' => 'CONTINUE', 'FastStartFailoverAutoReinstate' => 'TRUE', 'BystandersFollowRoleChange' => 'ALL', 'FastStartFailoverPmyShutdown' => 'TRUE', 'ExternalDestination1' => '', 'FastStartFailoverLagLimit' => '30', 'CommunicationTimeout' => '180' }, 'ConfigurationStatus' => 'SUCCESS' };
Please help!

Replies are listed 'Best First'.
Re: parse string into multidimensional hash
by Discipulus (Canon) on Feb 20, 2018 at 09:39 UTC
    Hello chickenman and welcome to the monastery and to the wonderful world of Perl!

    since this is your first post, contrary to monks habits, I offer you a working example, but remember: the monastery is not a code writing service! So remember the golden rule: more effort you show more help you, possibly, get in return.

    As you are in the need to parse a non standard format ( PS DGMGRL> SHOW CONFIGURATION; always give us as much information you can to help us to help you..;) the task is complex and the solution ugly (be brave!go learn MARPA)

    use strict; use warnings; use Data::Dumper; # create top level keys.. my %hash = ( Configuration => '', 'Protection Mode' => '', Databases => {}, Properties => {}, # Fast-Start Failover => '', # it's missing in your output.. 'Configuration Status' => '' ); # track the nasty last line.. my $last_line; # track the current key with subkeys my $current_key; while (<DATA>){ chomp; # skip empty lines next if /^$/; # remove leaading spaces s/^\s+//; # split on possible separators my @fields = split /\s*\-|:|=\s/,$_; # remove unneeded spaces from fields $fields[0] =~ s/\s+$//; $fields[1] =~ s/\s//g if defined $fields[1]; if ($fields[0] eq 'Configuration Status'){next} # second field present? it is a norma key (no subkeys) if (defined $fields[1]){ $fields[1]=~s/'//g; # some debug with print... print "fields = '$fields[0]' '$fields[1]'\n"; # are we processing a subkey? if ($current_key){ print "\tdefined current key\n"; #print "current -> $current_key - $fields[0]\n"; if (exists $hash{$current_key}){ print "\texists the key '$current_key'\n"; $hash{$current_key}{$fields[0]}=$fields[1]; } } else { # exists the toplevel key? if (exists $hash{$fields[0]}){ $hash{$fields[0]} = $fields[1]; } $current_key = undef; } } # else we are processing subkeys... else{ $current_key = $fields[0]; } $last_line = $fields[0]; if (eof){ $hash{'Configuration Status'} = $last_line; } } print Dumper \%hash; __DATA__ Configuration - DGCONF Protection Mode: MaxAvailability Databases: DB1 - Primary database DB2 - Physical standby database Properties: FastStartFailoverThreshold = '30' OperationTimeout = '30' FastStartFailoverLagLimit = '30' CommunicationTimeout = '180' ObserverReconnect = '0' FastStartFailoverAutoReinstate = 'TRUE' FastStartFailoverPmyShutdown = 'TRUE' BystandersFollowRoleChange = 'ALL' ObserverOverride = 'FALSE' ExternalDestination1 = '' ExternalDestination2 = '' PrimaryLostWriteAction = 'CONTINUE' Fast-Start Failover: DISABLED Configuration Status: SUCCESS

    That outputs:

    fields = 'Configuration' 'DGCONF' fields = 'Protection Mode' 'MaxAvailability' fields = 'DB1' 'Primarydatabase' defined current key exists the key 'Databases' fields = 'DB2' 'Physicalstandbydatabase' defined current key exists the key 'Databases' fields = 'FastStartFailoverThreshold' '30' defined current key exists the key 'Properties' fields = 'OperationTimeout' '30' defined current key exists the key 'Properties' fields = 'FastStartFailoverLagLimit' '30' defined current key exists the key 'Properties' fields = 'CommunicationTimeout' '180' defined current key exists the key 'Properties' fields = 'ObserverReconnect' '0' defined current key exists the key 'Properties' fields = 'FastStartFailoverAutoReinstate' 'TRUE' defined current key exists the key 'Properties' fields = 'FastStartFailoverPmyShutdown' 'TRUE' defined current key exists the key 'Properties' fields = 'BystandersFollowRoleChange' 'ALL' defined current key exists the key 'Properties' fields = 'ObserverOverride' 'FALSE' defined current key exists the key 'Properties' fields = 'ExternalDestination1' '' defined current key exists the key 'Properties' fields = 'ExternalDestination2' '' defined current key exists the key 'Properties' fields = 'PrimaryLostWriteAction' 'CONTINUE' defined current key exists the key 'Properties' fields = 'Fast' 'StartFailover' defined current key exists the key 'Properties' $VAR1 = { 'Configuration Status' => 'SUCCESS', 'Configuration' => 'DGCONF', 'Protection Mode' => 'MaxAvailability', 'Properties' => { 'ObserverOverride' => 'FALSE', 'ObserverReconnect' => '0', 'PrimaryLostWriteAction' => 'CONTINUE', 'FastStartFailoverThreshold' => '30', 'CommunicationTimeout' => '180', 'ExternalDestination2' => '', 'Fast' => 'StartFailover', 'FastStartFailoverLagLimit' => '30', 'BystandersFollowRoleChange' => 'ALL', 'ExternalDestination1' => '', 'OperationTimeout' => '30', 'FastStartFailoverPmyShutdown' => 'TRUE', 'FastStartFailoverAutoReinstate' => 'TRUE' }, 'Databases' => { 'DB1' => 'Primarydatabase', 'DB2' => 'Physicalstandbydatabase' } };

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Thank you so much for writing that piece of code. This is exactly what i was looking for. You definitely saved my day!
      Next time i'll try to be more precise.
Re: parse string into multidimensional hash
by BrowserUk (Patriarch) on Feb 20, 2018 at 08:17 UTC

    How is your existing code failing?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
      At the Moment i am doing the following
      But i have no clue how to break on Database: or Properties:
      $output =~ s/Configuration Status:\n/Configuration Status:/g; my @output = split /\n/, $output; for (@output) { $_ =~ s/\s//g; #print "$_\n"; my ($attr, $val) = split /[=,:,-]/, $_; $dg_config{$attr} = $val; }