regex - Parsing data with perl- capturing a range of text -


i'm writing code parse interfaces on network, looking configurations.. etc.

the data looks this:

interface fa1   mode access   port-security   mac-address sticky ! interface fa2   mode trunk ! 

basically starting "^interface " , ending "!".

my current algorithm "record" data need

foreach $line (@input) {     if ( $line =~ m/^interface.+\d/ && $line !~ m/interface embedded-service-engine|bri|tengigabitethernet|vlan|port-channel|atm|loopback/i) {         $record = 1;     }      #$int ne '' handle rest of file not in format     if( $line =~ m/!/ && $int ne '') {          #save data in format 'interface fa2,mode trunk'         #if interface doesn't have port-security         push(@intlist, join(','split("\r\n",$int))."\n") unless $int =~ m/port-security/;         $record=0;         $int='';     }     if ($record) {          $int.=$line;     }  } 

while works in case, i'd way it. i've searched , found can use range operator '..' on regex

which turns code :

@input # contains file @interfaces = grep (/^interface.+\d/ .. /!/, @input); 

which gives me interface data, problem every line single element in @interfaces array. how can split data /^interface.+\d/ .. /!/ 1 element in array without creating more loops?

the goal down 1 element can scan interfaces don't want @ interface embedded-service-engine|bri|tengigabit interfaces have correct configurations.

have @ $/ because think that'll help. it's record separator - defaults \n.

then can apply regular expressions current 'chunk' pull out data require - default regular expression/capture group applies $_ implicit variable.

e.g.

#!/usr/bin/perl use strict; use warnings;   local $/ = '!';  while ( <data> ) {     ( $interface ) = m/interface (\w+)/i;     next if $interface =~ m/embedded-service-engine/;     ( $mode ) = m/mode (\w+)/;      print "$interface $mode\n";      print "---next record---\n"; }  __data__ interface fa1   mode access   port-security   mac-address sticky ! interface fa2   mode trunk ! 

if need keep data other uses (e.g. 'process go' isn't suitable) tool job hash.

you can either use above - , populate hash particular keys you're interested in - or use magic of map you.

#!/usr/bin/perl use strict; use warnings;  use data::dumper; local $/ = '!';  %interfaces;   while ( <data> ) {     ( $interface ) = m/interface (\w+)/i;      next if $interface =~ m/embedded-service-engine/;     %interface_values =  map { ( $key, $value ) = split; $key, $value || 1 } grep { /\w/ } split ( "\n" );     $interfaces{$interface} = \%interface_values; }  print dumper \%interfaces  __data__ interface fa1   mode access   port-security   mac-address sticky ! interface fa2   mode trunk ! 

that map line basically:

  • splits current record on \n each line.
  • filters 'not word' values (so blank lines , !)
  • splits each line on whitepace, key , value pair.
  • if no value defined, sets 1. (so in example, port-security )
  • populates hash these key-value pairs.
  • and updates %interfaces hash each interface id.

giving like:

$var1 = {           'fa1' => {                      'port-security' => 1,                      'mode' => 'access',                      'interface' => 'fa1',                      'mac-address' => 'sticky'                    },           'fa2' => {                      'mode' => 'trunk',                      'interface' => 'fa2'                    }         }; 

Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -