0

I need another help, this is in continuation of Extract data from the nested parenthesis in bash,

I have input data like below with multiple blocks, I want to put a logic to check for network vlans block alone, exclude the auths, network trunk, network interface blocks.

auths remote {
    roles {
        admin {
            role administrator
        }
        readonly {
            role read-only
        }
    }
}

auths ldap system { 
    login-attribute uid
    port 636
}

network vlan internal-vlan {
    description "internal-use"
    interfaces {
        1.1 { }
        1.2 { }
    }
    MTU {
    1500
    }
}
network vlan external-vlan {
    description "external-use"
    interfaces {
       2.1 { }
       2.2 { }
    }
    MTU {
    1500
    }
}
network vlan dummy-vlan {
    description "dummy-use"
    interfaces {
       1.1 { }
    }
}

network trunk {
    description "none"
}

network interface 1.1 {
    Status {
        UP
    }
}
network interface 1.2 {
    Status {
        UP
    }
}
network interface 2.1 {
    Status {
        DOWN
    }
}
network interface 2.2 {
    Status {
        UP
    }
}
system update settings {
    frequency monthly
}

I want similar output as before. I think I have to make a parent function and put a if logic to check if the block starts with "network vlan" then trigger the proc network.

If I can put a if logic to check for string "network vlan" and then trigger a proc, i think i can relate for rest of configs and create new functions wherever needed.

2
1

Since your last question asked for perl solutions, here is one that is fairly simple, except for the recursive regular expression needed to match nested {...} blocks, which I have separated out into the variable $balanced. This also allows it to be used 3 times, once to match the block after each of the keywords network vlan, interfaces, and MTU.

#!/usr/bin/perl
use strict;
open(F,"datafile") or die;
my $data = join("",<F>);
my $balanced = qr/
 (    ( [^{}]*+
        ({     (?-2)*   })?
      )*
 )/x;
while($data =~ m/network\s+vlan\s+([^ {]+)\s*{$balanced}/g){
    my $vlan = $1;
    my $body = $2;
    $body =~ m/description\s*("[^\"]*")/;
    my $desc = $1;
    $body =~ m/interfaces\s*{$balanced}/;
    my $intf = $1;
    $intf =~ s/\s+/ /g;
    my $mtu = 'none';
    $mtu = $1  if($body =~ m/MTU\s*{$balanced}/);
    $mtu =~ s/\s+/ /g;
    print "$vlan, $desc,$intf,$mtu\n";
}

$balanced is used once you have matched the opening { of a block, and goes on to match anything that is not { or } by using [^{}]*. This is optionally followed by {, the recursion going back 2 parentheses, and }, namely {(?-2)*}. This is inside ()? to make it optional. I am not a perl expert, so there is undoubtably a more optimal version of this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.