awk with range but matches pattern

To match range, the command is:

awk '/BEGIN/,/END/'

but what I want is the range is printed only if there is additional pattern that matches in the range itself? maybe like this:

awk '/BEGIN/,/END/ if only in that range there is /pattern/'

Thanks

awk '/BEGIN/,/END/ { if ($0 ~ /pattern/) print}'

Thanks SriniShoo,

The problem with that command is it will only show the line that contains the pattern, not the range that contains the pattern. How to fix this?

Please provide an input and output so that we can understand your requirement

file content:

abc
begin
def
ghi
pattern1
end
begin
pattern1
jkl
end
begin
lyt
end
mno
pqr
begin
stu
vwx
yza
end
def
ghi

print lines between "begin" and "end" only if it has pattern1 in that range
The output:

begin
def
ghi
pattern1
end

begin
pattern1
jkl
end

Try :

$ awk '/begin/{s=""}{s=s ? s ORS $0:$0}/end/{if(s~/pattern1/)print s RS}' file
begin
def
ghi
pattern1
end

begin
pattern1
jkl
end
1 Like
sed -n "/begin/,/end/{H;/begin/h;}; /end/{g;/pattern1/p;}" file
1 Like

Thanks Akshay. Your codes work. Could you please explain the codes?

awk '/begin/{s=""}{s=s ? s ORS $0:$0}/end/{if(s~/pattern1/)print s RS}'

Glad to know that it worked for you..

So here is details

/begin/{s=""} --> Search keyword begin, if keyword found then empty variable s s=""

{s=s ? s ORS $0:$0} --> append currennt line to variable s with ORS (output record separator) if s is not empty, if variable s is empty then s = current line , default value of ORS is the string "\n" ; i.e., a newline character

/end/ --> So now search for end keyword, if end is found, then check for pattern1

if(s~/pattern1/)print s RS --> check whether variable s we used above contains pattern1, if condition is true print variable s and Record Separator (RS).

1 Like