Print lines between two patterns , the awk way …
Note: My awk
guide.
Example input file:
test -3 test -2 test -1 OUTPUT top 2 bottom 1 left 0 right 0 page 66 END test 1 test 2 test 3
The standard way ..
awk '/OUTPUT/ {flag=1;next} /END/{flag=0} flag {print}' inputFile
Output:
top 2 bottom 1 left 0 right 0 page 66
Self-explained indented code:
awk ' /OUTPUT/ {flag=1;next} # Initial pattern found --> turn on the flag and read the next line /END/ {flag=0} # Final pattern found --> turn off rhe flag flag {print} # Flag on --> print the current line ' inputFile
The first optimization is to get rid of the print , in awk when a condition is true print is the default action , so when the flag is true the line is going to be echoed.
To delete de NEXT statement , in order o prevent printing the TAG line, we need to activate the flag after the “OUTPUT” pattern discovery and after the flag evaluation.
A slight variation of the program flow and we’re done:
awk '/END/{flag=0}flag;/OUTPUT/{flag=1}' inputFile
PD: What if we only want to print the lines enclosed between the OUTPUT && END tags ? check this …
sed -n ‘/OUTPUT/,/END\ related/p’
that should the same job, only more elegantly.
Well , not exactly the same:
To exclude the tags you must go a little further:
See: http://sed.sourceforge.net/sedfaq4.html#s4.24
We will have the same inconvenients .
I still prefer awk for excluding the tags.
Cheers and thanks for the feedback.
Is there any way to eliminate repetition. For Eg. if i am having a string like below and i need only the first pattern of string between OUTPUT to END
OUTPUT
top 2
bottom 1
left 0
END
right 0
OUTPUT
page 66
test 1
test 2
test 3
END
Of course, just use the exit statement when finding the first “END” tag.
Thank you so much klashxx that helped………
Then, how can we get the lines that are in between the next same two strings?
Please describe what you are trying to accomplish with a clear example
is there any way to print the lines between the patterns after some pattern is matched
eg:
xyz
abc
asd
sdf
fghj
kje
dnsk
i need a script which will have to search in the file whether it has ” xyz” and “abc” are in contiguous lines and if it has then needs to print the text between “asd” & “dnsk”.
pls respond to this ques asap….
This way:
Hi. Thanks for this blog entry. I stumbled across on my way to search for an extension of multimarkdown. I would like to define blocks:
and transform it to latex like:
I thought what you showed here would bring me there but I couldn’t figure out how. Any hints?
BR
Hi Christof, for your problem i would use a perl one-liner to perform an inplace replacement:
Hi and thanks for your answer. This is really concise, however, I did not clarify that ID is a variable string. So I have to read it somehow at the start of the block and use it again at the end. That got me down…
Ok , i got you , there’re many ways to solve your problem , give this a try;
Perfekt. Thank you again.
Actually i wanted this with one condition:
log file:
asd
START
as
erg
ege
4t
END
lgjlkej
nelgkl
START
lrkglk
egiorgklk
gljegj
google
lwekglk
END
So i need the lines between START and END having ‘google’ under that. Please help.
This solution use an array ,it rewinds the index if the “google” pattern is not present between the tags , so having this text file:
The code will be:
And the result:
Reblogged this on justanotherhumanoid and commented:
Beautiful display of AWK craftsmanship. Dont miss the solutions in the comments section.
Hi,
with similar senario, I need the output include the START and END string, output will be like
START
google
saas
END
START
lrkglk
egiorgklk
gljegj
google
lwekglk
END
Please help
Thanks
Cithosi
Hello ,just change the matching order in awk in order to set a positive flag before the “printing”:
Or use this concise sed:
Is up to you , but I suppose sed performance will be slightly better for large files.
Thanks for the quick reply, I need to print only if “google” exist within the search block please,my file have over 3000 lines of text.
Thanks
Ok, having this sample file:
You can apply this gawk (most Linux , if not you will need to delete the elements of the array one-by-one)
The result wiil be:
Machinery is simple: store the text between tags but show only if pattern is found.
It worked, much appriciated,
Thanks
Hi Klashxx, thanks for this incredibly helpful post. I have one question though. I want to input the Begin tag as a command line argument. This is what I tried –
awk ‘BEGIN{a=’$1′}/END/{exit}flag;/a/{flag=1}’ text.txt
but doesn’t work. Whats the solution?
Hi Rahul, you can go the standard path, using the -v flag:
Or the tricky way:
See Passing values to awk , the trick.
HI Klash
Need help in getting one awk statement , awk in between two patterns and print the line if there is only one line between the pattern
I want to print abcd , that is one line in between
ex
———–
abcd
———–
efgh
ijklm
———–
Having:
$ cat ex
---
abcd
---
efgh
ijklm
---
xxgfgh
---
This code will do the trick:
$ awk '/^---/{if(i==1){print a[i]};i=0;next}{a[++i]=$0}' ex
abcd
xxgfgh
Hi,
I want to print the lines between the markers patterns, but along with that i also want to print the lines matching other patterns as well.
For example: If my input file is—
START
as
erg
ege
END
abc
xyz
pqr
xyz
asd
NOW
lrkglk
egiorgklk
gljegj
google
NOT
I want to print lines between START and END,NOW and NOT, and the lines matching xyz. i.e. my output should be:
START
as
erg
ege
END
xyz
xyz
NOW
lrkglk
egiorgklk
gljegj
google
NOT
Please help me. It’s very urgent!!!
awk ‘/START|NOW/{flag=1}flag||/xyz/;/END|NOT/{flag=0}’ file