Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Juniper config file parsing approach 1

Status
Not open for further replies.

hcvink

Technical User
Feb 17, 2010
11
NL
I want to gather some information from a config file, but I am strugling with the way to get the information I need.

The config file looks similar to this:
Code:
groups {
  [b][blue]re0 {
    system {
      host-name my-re0;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
          unit 0 {
            family inet {
               address 10.255.2.40/24;
            }
          }
      }
    }
  }[/blue][/b]
  re1 {
    system {
      host-name my-re1;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
        unit 0 {
          family inet {
            address 10.255.2.41/24;
          }
        }
      }
    }
  }
}

I am not directly asking for a solution but more for an approach on handling files like this.

For instance how would I go about grabbing the re0 information (blue bold)?
 
You could try something like this, which uses counteres to keep track of the brace depth and a flag to track whether or not we are in an "interesting" part of the file still.

Code:
[COLOR=#006600]#!/usr/bin/perl -w[/color]

[COLOR=#0000FF]use[/color] strict;

[COLOR=#0000FF]my[/color] $bracedepth=[COLOR=#FF0000]0[/color];
[COLOR=#0000FF]my[/color] $targetdepth=[COLOR=#FF0000]0[/color];
[COLOR=#0000FF]my[/color] $targetfound=[COLOR=#FF0000]0[/color];
[COLOR=#0000FF]my[/color] $targetstring=[COLOR=#808080]"re0"[/color];

[COLOR=#0000FF]while[/color] (<>) {
        [COLOR=#0000FF]if[/color] (!$targetfound && /$targetstring/) {
                $targetfound=[COLOR=#FF0000]1[/color];
                $targetdepth=$bracedepth;
        }
        [COLOR=#0000FF]if[/color] (/{/) { $bracedepth++ }
        [COLOR=#0000FF]if[/color] (/}/) { $bracedepth-- }
        [COLOR=#FF0000]print[/color] [COLOR=#0000FF]if[/color] ($targetfound);
        [COLOR=#0000FF]if[/color] ($bracedepth <= $targetdepth) { $targetfound=[COLOR=#FF0000]0[/color] }
}

Annihilannic.
 
To grab the re0 section, take advantage of the (?PARNO) feature in perlre to match balanced braces:

Code:
use strict;
use warnings;

my $data = do { local $/; <DATA> };

my $re0 = $data =~ m{(\bre0\s*({(?:(?>[^{}]+)|(?-1))*}))}
	? $1
	: die "re0 not found in string";

print $re0, "\n";

__DATA__
groups {
  re0 {
    system {
      host-name my-re0;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
          unit 0 {
            family inet {
               address 10.255.2.40/24;
            }
          }
      }
    }
  }
  re1 {
    system {
      host-name my-re1;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
        unit 0 {
          family inet {
            address 10.255.2.41/24;
          }
        }
      }
    }
  }
}

- Miller
 
Thanks for the replies.

When I use the regular expression I get:

Code:
Sequence (?-1...) not recognized before HERE mark in regex m/(\bre0\s*({(?:(?>[^{}]+)|(?-1 << HERE ))*}))/

I also tried Text::Balanced but I do not have the rights to install modules. Using Require does not work either it fails in another module.

I use an older perl version btw. This is perl, v5.6.1 built for sun4-solaris. Might that be the reason the above is not working?

 
Yes, the (?PARNO) feature wasn't introduced until perl 5.10. I think your best bet is to just upgrade to tell the truth.

However, there is an older style of recursive regex's that might work, although I'm not sure your version of perl supports it either:

Code:
use strict;
use warnings;

my $data = do { local $/; <DATA> };

our $braces_re;
$braces_re = qr{{(?:(?>[^{}]+)|(??{$braces_re}))*}};

my $re0 = $data =~ m{(\bre0\s*($braces_re))}
    ? $1
    : die "re0 not found in string";

print $re0, "\n";

__DATA__
groups {
  re0 {
    system {
      host-name my-re0;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
          unit 0 {
            family inet {
               address 10.255.2.40/24;
            }
          }
      }
    }
  }
  re1 {
    system {
      host-name my-re1;
    }
    interfaces {
      fxp0 {
        description "10/100 Management interface";
        unit 0 {
          family inet {
            address 10.255.2.41/24;
          }
        }
      }
    }
  }
}

Note: The delayed initialization of $braces_re is intentional to avoid bugs introduced in later version of perl.

- Miller
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top