On 16/11/2010 17:01, Vincent Li wrote:
Hi List,

I have a text test.txt file looks like below:

stp instance 0 {
    interfaces 1.1 {
          external path cost 20000
          internal path cost 20000
       }
    vlans {
       internal
       vlan10
    }
}
profile http http_global {
    defaults from http
    max header size 38912
    encrypt cookies {
       "F-P-SES"
    }
}
profile tcp tcp {
    reset on timeout enable
    time wait recycle enable
    delayed acks enable
    proxy mss disable
}
vlan vlan10 {
    tag 1330
    interfaces tagged 1.1
}
route domain 10 {
    parent id 0
    description "RD10"
    vlans vlan10
}
route domain 12 {
    parent id 10
    description "RD12"
    vlans vlan12
}

how can I find a specific profile { } block and remove/replace that
part from the file, for example, I want to remove below block or
replace it with emtpy blank line

profile tcp tcp {
    reset on timeout enable
    time wait recycle enable
    delayed acks enable
    proxy mss disable
}

and the { } could have nested { } block too.

I tried:

perl -e '$/=undef;foreach $profile (<>=~m/profile.*?{.*?}/gs) { print
"$profile\n"; }'<  /tmp/test.txt

to search and print out the all profile, any tips/sample codes would
be very much apprecaited.

Hi Vincent

It is correct that arbitrarily nested blocks cannot be parsed with a single regular expression, but there is also no need for anything elaborate.

The program below simply keeps track of the level of nesting by adding the number of opening braces and subtracting the number of closing braces on each line of the data file. When the level reaches zero a complete block has been read and its label determines whether or not it should be output.

HTH,

Rob


use strict;
use warnings;

my %exclude;
while(<DATA>) {
  chomp;
  next unless /(\w[\w\s-]*\w)/;
  $exclude{$1}++;
}

open my $profile, '<', 'profile.txt' or die $!;

my $label = '';
my $block = '';
my $level = 0;

while (<$profile>) {

  if ($level == 0 and /(\w[\w\s-]*\w)/) {
    $label = $1;
  }

  $block .= $_;

  $level += tr/{//;
  $level -= tr/}//;

  if ($level == 0) {
    if (not $exclude{$label}) {
      print $block;
    }
    $block = $label = '';
  }
}

__DATA__
profile auth ssl_ocsp
profile stats stats
profile stream stream
profile auth tacacs
profile tcp tcp
profile tcp tcp-cell-optimized
profile tcp tcp-lan-optimized
profile tcp tcp-wan-optimized
profile udp udp

--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/


Reply via email to