in reply to Parsing out mulitiple blocks of interesting data in files / ignoring other contents

Hello GeorgMN,

Although use of the range operator in scalar context (i.e., the flip-flop operator) is often useful for this type of problem, in this case you need a flag which can be set and cleared according to more complicated conditions. The following shows one way to do this:

#! perl use strict; use warnings; my @block; my $in_block = 0; while (<DATA>) { if (/^interface/) { push @block, $_; $in_block = 1; } elsif ($in_block) { if (/^!/) { print for (@block, $_); @block = (); $in_block = 0; } elsif (/^\s*shutdown/) { @block = (); $in_block = 0; } else { push @block, $_; } } } __DATA__ # contents of file: ! blah ! blah blah ! # start to grab section here with start (/interface/) interface GigabitEthernet1/1/2 description PC Trunk switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk queue-set 2 priority-queue out mls qos trust dscp storm-control broadcast level 1.00 storm-control multicast level 1.00 spanning-tree guard loop channel-protocol lacp channel-group 1 mode active ! # ^ end section with (/!/) # ignore entire block of data when after (/interface/) a (/shutdown/) +is seen before (/!/)" interface GigabitEthernet1/1/3 shutdown ! interface GigabitEthernet1/1/4 shutdown ! interface TenGigabitEthernet1/1/1 ! interface TenGigabitEthernet1/1/2

Output:

22:16 >perl 1563_SoPW.pl interface GigabitEthernet1/1/2 description PC Trunk switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk queue-set 2 priority-queue out mls qos trust dscp storm-control broadcast level 1.00 storm-control multicast level 1.00 spanning-tree guard loop channel-protocol lacp channel-group 1 mode active ! interface TenGigabitEthernet1/1/1 ! 22:16 >

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

  • Comment on Re: Parsing out mulitiple blocks of interesting data in files / ignoring other contents
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Parsing out mulitiple blocks of interesting data in files / ignoring other contents
by GeorgMN (Acolyte) on Mar 02, 2016 at 13:17 UTC
    Would you be so kind to paraphrase what you are doing in your code please. Thank you again.

      The flag variable $in_block keeps track of whether the current line is in a block of interest (because it began with a line starting with the word interface). If we are currently not in such a block, the only thing to be done is to test the current line to determine whether it begins a new such block (if (/^interface/)). If we are already within a block of interest, we will store the current line in the @block array unless the current line (1) begins with the block termination character, !, or (2) begins (after optional whitespace) with the block discard word shutdown.

      When condition (1) is satisfied, we know that the current block has terminated successfully, so we print it out. But if condition (2) occurs, the current block is to be ignored. In either case, the block has ended so we reset the flag to indicate that we are no longer within a block of interest.

      As mentioned above, if we are within a block of interest but the current line satisfies neither condition (1) nor condition (2), then we save the line by pushing it onto the array variable @block, which holds all the lines of the current block that we have read so far. Whenever condition (1) or condition (2) is satisfied, the block ends so we empty the array @block by assigning the empty list to it: @block = ().

      Hope that’s a little clearer,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Thank you very much sir. Very helpful. Have a nice day.

      What parts of it are causing you trouble?

      But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Re^2: Parsing out mulitiple blocks of interesting data in files / ignoring other contents
by GeorgMN (Acolyte) on Mar 02, 2016 at 13:27 UTC

    Hi Athanasius, Sadly the code does not seem not work the way i hoped. Can you help me out further?

    #!/usr/bin/perl -w # use strict; use warnings; my $CONFIGFILE = $ARGV[0]; open(FILE, $CONFIGFILE) || die "file not found\n"; my @block; my $in_block = 0; while (<FILE>) { if (/^interface/) { push @block, $_; $in_block = 1; } elsif ($in_block) { if (/^!/) { print for (@block, $_); @block = (); $in_block = 0; } else { push @block, $_; } } } ######### OUTPUT OF SCRIPT ############ interface Port-channel1 description HIS51-10 switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk storm-control broadcast level 1.00 storm-control multicast level 1.00 spanning-tree guard loop ! interface FastEthernet0 no ip address shutdown ! interface GigabitEthernet1/0/1 switchport access vlan 100 shutdown spanning-tree portfast ! interface GigabitEthernet1/0/2 description Internet Swisscom switchport access vlan 100 speed 1000 duplex full ! interface GigabitEthernet1/0/3 shutdown ! interface GigabitEthernet1/0/4 shutdown ! interface GigabitEthernet1/0/5 shutdown ! interface GigabitEthernet1/0/6 shutdown ! interface GigabitEthernet1/0/7 shutdown ! interface GigabitEthernet1/0/8 shutdown ! interface GigabitEthernet1/0/9 shutdown ! interface GigabitEthernet1/0/10 shutdown ! interface GigabitEthernet1/0/11 shutdown ! interface GigabitEthernet1/0/12 description A-CHHER-IF01-1 /4 switchport access vlan 100 spanning-tree portfast ! interface GigabitEthernet1/0/13 shutdown ! interface GigabitEthernet1/0/14 description A-CHHER-IF01-2 /4 switchport access vlan 100 ! interface GigabitEthernet1/0/15 shutdown ! interface GigabitEthernet1/0/16 shutdown ! interface GigabitEthernet1/0/17 shutdown ! interface GigabitEthernet1/0/18 shutdown ! interface GigabitEthernet1/0/19 shutdown ! interface GigabitEthernet1/0/20 switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk shutdown ! interface GigabitEthernet1/0/21 shutdown ! interface GigabitEthernet1/0/22 shutdown ! interface GigabitEthernet1/0/23 shutdown ! interface GigabitEthernet1/0/24 shutdown ! interface GigabitEthernet1/1/1 description HIS51-10 G1/1/1 switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk queue-set 2 priority-queue out mls qos trust dscp storm-control broadcast level 1.00 storm-control multicast level 1.00 spanning-tree guard loop channel-protocol lacp channel-group 1 mode active ! interface GigabitEthernet1/1/2 description HIS51-10 G1/1/2 switchport trunk encapsulation dot1q switchport trunk native vlan 100 switchport mode trunk queue-set 2 priority-queue out mls qos trust dscp storm-control broadcast level 1.00 storm-control multicast level 1.00 spanning-tree guard loop channel-protocol lacp channel-group 1 mode active ! interface GigabitEthernet1/1/3 shutdown ! interface GigabitEthernet1/1/4 shutdown ! interface TenGigabitEthernet1/1/1 ! interface TenGigabitEthernet1/1/2 ! interface Vlan1 no ip address no ip route-cache shutdown

      You’ve omitted this part of the code:

      elsif (/^\s*shutdown/) { @block = (); $in_block = 0; }

      which tests for the “ignore entire block” keyword shutdown — so of course blocks containing that word are still being printed.

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Works beautifully! Thank you kindly and greetings. GT
        Doh - i am such a noob. Sorry. Testing...