Ggdw
Ggdw

Reputation: 2699

perl find a pattern between two patterns inside bash

I am looking for a regular expression using perl in a bash file (*.sh). I need to find a dynamic pattern between two pattern.

For example:

some data 
.
.
.
Pattern1
.. data
Dynamic_Pattern
...data
Pattern2
.
.
data
.
.
Pattern1
..data
Pattern2

the output will be:

Pattern1
.. data
dynamic pattern
...data
Pattern2

I found this code on the web:

perl -n0e 'while (/Pattern1.*?((?=Pattern2)|(?=$))/sg) {$x=$&;print $x if $x=~/$Dynamic_Pattern/}' file

the problem is that it does not work if the Dynamic_Pattern id dynamic, only if it static

Upvotes: 2

Views: 406

Answers (2)

marderh
marderh

Reputation: 1256

You must pass the "dynamic" part as argument to the perl-oneliner. Otherwise perl treats it as "his" variable, which is undefined of course. You can enable basic commandline-arguments with the -s-switch (look here). The \Q before the pattern should ensure that potentially problematic characters are quoted.

perl -sn0e 'while (/Pattern1.*?((?=Pattern2)|(?=$))/sg) {$x=$&;print $x if $x=~/\Q$dynpattern/}' -- -dynpattern="$Dynamic_Pattern" file 

Upvotes: 1

Birei
Birei

Reputation: 36282

One option is to pass two arguments to the script. The first one the dynamic pattern to search, and the second one the file with the content. The script will use flip-flop to extract the range of lines between both edge patterns.

Assing the value:

searched_pattern="Dynamic_Pattern"

And run the perl script:

perl -ne '
    BEGIN { $pat = shift }
    if ( my $range = ( m/\A(?i)pattern1\b/ ... m/\A(?i)pattern2\b/ ) ) {
        $data .= $_;
        if ( ( q|E0| eq substr $range, -2 ) && ( $data =~ m/^\Q${pat}\E\b/m ) ) {
            printf qq|%s|, $data;
        }
        else {
            next;
        }
    }

    if ( $data ) { undef $data }
' "$searched_pattern" infile

It yields:

Pattern1
.. data
Dynamic_Pattern
...data
Pattern2

Upvotes: 1

Related Questions