Extracting specific lines with Perl

前端 未结 4 769
孤城傲影
孤城傲影 2021-01-20 20:14

I am writing a perl program to extract lines that are in between the two patterns i am matching. for example the below text file has 6 lines. I am matching load balancer and

相关标签:
4条回答
  • 2021-01-20 20:27

    If you prefer a command line variation:

    perl -ne 'print if m{\*load balancer\*}..m{\*end\*} and !m{\*load|\*end}' file
    
    0 讨论(0)
  • 2021-01-20 20:31

    You can use the flip-flop operator.

    Additionally, you can also use the return value of the flipflop to filter out the boundary lines. The return value is a sequence number (starting with 1) and the last number has the string E0 appended to it.

    # Define the marker regexes separately, cuz they're ugly and it's easier
    # to read them outside the logic of the loop.
    my $start_marker = qr{^ \s* \*\*load \s balancer\*\* \s* $}x;
    my $end_marker   = qr{^ \s* \*\*end\*\* \s* $}x;
    
    while( <DATA> ) {
        # False until the first regex is true.
        # Then it's true until the second regex is true.
        next unless my $range = /$start_marker/ .. /$end_marker/;
    
        # Flip-flop likes to work with $_, but it's bad form to
        # continue to use $_
        my $line = $_;
    
        print $line if $range !~ /^1$|E/;
    }
    
    __END__
    foo
    bar
    **load balancer** 
    new 
    old
    good
    bad
    **end**
    baz
    biff
    

    Outputs:

    new 
    old
    good
    bad
    
    0 讨论(0)
  • 2021-01-20 20:48

    You can use the flip-flop operator to tell you when you are between the markers. It will also include the actual markers, so you'll need to except them from the data collection.

    Note that this will mash together all the records if you have several, so if you do you need to store and reset @array somehow.

    use strict;
    use warnings;
    
    my @array;
    while (<DATA>) {
        if (/^load balancer$/ .. /^end$/) {
            push @array, $_ unless /^(load balancer|end)$/;
        }
    }
    
    print @array;
    
    __DATA__
    load balancer
    new 
    old
    good
    bad
    end
    
    0 讨论(0)
  • 2021-01-20 20:49

    For files like this, I often use a change in the Record Separator ( $/ or $RS from English )

    use English qw<$RS>;
    local $RS = "\nend\n";
    
    my $record = <$open_handle>;
    

    When you chomp it, you get rid of that line.

    chomp( $record );
    
    0 讨论(0)
提交回复
热议问题