Gui O
Gui O

Reputation: 383

Perl read file from string to string

I'm reading a file having this structure :

Policy Map <mypolicy>
    Class <myclass1>
      priority 1150 (kbps) 106250
     police cir 1152000 bc 144000 be 144000
       conform-action set-dscp-transmit ef
       exceed-action drop
       violate-action drop
    Class <myclass2>
      bandwidth remaining 60 (%)
       packet-based wred, exponential weight 9

I only want to catch this paragraph :

Class <myclass1>
     priority 1150 (kbps) 106250
     police cir 1152000 bc 144000 be 144000
     conform-action set-dscp-transmit ef
     exceed-action drop
     violate-action drop

I am trying to use this :

open(DATA,$fichier) || die ("Erreur d'ouverture de $fichier\n") ;
while (<DATA>) {
    if (/ Class <myclass1>/ .. / Class/) {
        print $_ ;
        # and insert into variable
    }
}
close(DATA);

I tried it different ways but i still can't get it.

Upvotes: 1

Views: 104

Answers (2)

Miller
Miller

Reputation: 35208

There are two details to using the Range Operator .. that you need to take into account for your problem:

  1. Use the three dot form ... if you don't want the range to test the right operand until the next evaluation.

  2. Use the return value of the range to filter out the ending condition.

    The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint.

Demonstrated below:

use strict;
use warnings;

while (<DATA>) {
    if (my $range = /Class <myclass1>/ ... /Class/) {
        print if $range !~ /E/;
    }
}

__DATA__
Policy Map <mypolicy>
    Class <myclass1>
      priority 1150 (kbps) 106250
     police cir 1152000 bc 144000 be 144000
       conform-action set-dscp-transmit ef
       exceed-action drop
       violate-action drop
    Class <myclass2>
      bandwidth remaining 60 (%)
       packet-based wred, exponential weight 9

Outputs:

Class <myclass1>
  priority 1150 (kbps) 106250
 police cir 1152000 bc 144000 be 144000
   conform-action set-dscp-transmit ef
   exceed-action drop
   violate-action drop

Upvotes: 0

mpapec
mpapec

Reputation: 50677

You'll have to use three dots ... range operator, as second condition matches on the same line and range is immediately closed,

if (/Class <myclass1>/ ... /Class/)

You can think of ... like match second condition /Class/ a little later.

From perldoc

If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two. In all other regards, "..." behaves just like ".." does.

Upvotes: 4

Related Questions