Sed / awk - print text between patterns overlaid on multiple lines

I am new to scripting and tried to learn how to extract any text that exists between two different templates. However, I still cannot figure out how to extract text between two patterns in the following scenario:

If I have an input file:

Hi I would like to print text between these patterns 

and the expected output is as follows:

 I would like to print text between these 

i.e. my first search pattern is β€œHello” and skip this pattern, but type everything that exists on the same line as the corresponding pattern. My second search pattern is β€œpatterns,” and I would like to completely avoid printing this line or any lines outside it.

I tried the following:

 sed -n '/Hi/,/patterns/p' test.txt 

[exit]

 Hi I would like to print text between these patterns 

Next I tried:

 `awk ' /'"Hi"'/ {flag=1;next} /'"pattern"'/{flag=0} flag { print }'` test.txt 

[exit]

 to print text between these 

Can someone help me in deciding how to achieve this? thanks in advance

+8
bash awk sed
source share
4 answers

You have the right idea, a mini-state machine in awk , but you need small mods according to the following transcript:

 pax> echo 'Hi I would like to print text between these patterns ' | awk ' /patterns/ { echo = 0 } /Hi / { gsub("^.*Hi ", "", $0); echo = 1 } { if (echo == 1) { print } }' 

Or in a concise form:

 awk '/patterns/{e=0}/Hi /{gsub("^.*Hi ","",$0);e=1}{if(e==1){print}}' 

Result:

 I would like to print text between these 

upon request.

How it works is as follows. Initially, the variable echo 0 means that there will be no echo.

Each line is checked in turn. If it contains patterns , the echo is disabled.

If it contains Hi followed by a space, the echo is turned on and gsub used to change the line to get rid of everything to Hi .

Then regardless of whether the line is on (possibly changed) when the echo flag is on.

Boundary cases will now appear, such as:

  • strings containing two occurrences of Hi ; or
  • strings containing something in front of patterns .

You did not indicate how they should be handled so that I would not worry, but the basic concept should be the same.

+6
source share

Updated solution for deleting strings "patterns":

 $ sed -n '/^Hi/,/patterns/{s/^Hi //;/^patterns/d;p;}' file I would like to print text between these 
+3
source share

This may work for you (GNU sed):

 sed '/Hi /!d;s//\n/;s/.*\n//;ta;:a;s/patterns.*$//;tb;$!{n;ba};:b;/^$/d' file 
+2
source share

Just set flag (f) when you find + replace Hi at the beginning of the line, clear it when you find patterns, then call default printing when setting the flag:

 $ awk 'sub(/^Hi /,""){f=1} /patterns/{f=0} f' file I would like to print text between these 
+1
source share

All Articles