Start_pattern
abc
d End_pattern
Start_pattern
abc
d
ef
ghij
klm
no End_pattern
Start_pattern
abc
def
hij End_pattern
Start_pattern
abc
dhi
jklm End_pattern
With gawk
, which supports multi char RS
:
gawk 'BEGIN{RS=ORS="End_pattern"}/ef/' file
Output:
Start_pattern
abc
d
ef
ghij
klm
no End_pattern
Start_pattern
abc
def
hij End_pattern
Explanation:
# Split records based on the End_pattern
BEGIN{RS=ORS="End_pattern"}
# Print records that contain the search term
/ef/
Btw, for cosmetic reasons you might want to append a newline at the end out the output:
gawk 'BEGIN{RS=ORS="End_pattern"}/ef/;END{printf "\n"}' file
PS: While the above solution works with gawk
only, it is also possible to achieve that with a simple awk
script which is compatible to POSIX, meaning it works with any awk
:
awk '{b=b$0"\n"}/End_pattern/{if(b~/ef/){printf "%s",b};b=""}' file
Explanation:
# Append the current line plus a newline to b(uffer)
{b=b$0"\n"}
# Once End_pattern is found ...
/End_pattern/{
# Check if the buffer contains the search term
if(b~/ef/){
# Print the buffer when the term was found
printf "%s",b
}
# Clear the buffer
b=""
}
awk '{b=b$0"\n"}/End_pattern/{if(b~/ef/){printf "%s",b};b=""}' file