I have a log file trace.log
. In it I need to grep for the content contained within the strings <tag>
and </tag>
. There are multiple sets of this pair of strings, and I just need to return the content between last set (in other words, from the tail
of the log file).
Extra Credit: Any way I can return the content contained within the two strings only if the content contains "testString"?
Thanks for looking.
EDIT: The search parameters and are contained on different lines with about 100 lines of content separating them. The content is what I'm after...
The command is relatively simple. We start by finding the string we require using grep. Next, Grep will list all the string occurrences, and finally, we pipe the output to the tail and locate the last line of the output.
The strrchr() function finds the last occurrence of c (converted to a character) in string .
grep is a command line tool that can search for matching text in a file, or in output from other commands. It's included by default in most Linux distributions and is also available for Windows and Mac. To perform a simple search, enter your search string followed by the file you want to search.
Use tac
to print the file the other way round and then grep -m1
to just print one result. The look behind and look ahead checks text in between <tag>
and </tag>
.
tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)'
Given this file
$ cat a <tag> and </tag> aaa <tag> and <b> other things </tag> adsaad <tag>and last one</tag> $ tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)' and last one
EDIT: The search parameters and are contained on different lines with about 100 lines of content separating them. The content is what I'm after...
Then it is a bit more tricky:
tac file | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p' | tac
The idea is to reverse the file and use a flag p
to check if the <tag>
has appeared yet or not. It will start printing when </tag>
appears and finished when <tag>
comes (because we are reading the other way round).
split($0, a, "</tag>"); $0=a[1];
gets the data before </tag>
split($0, a, "<tag>" ); $0=a[2];
gets the data after <tag>
Given a file a
like this:
<tag> and </tag> aaa <tag> and <b> other thing come here and here </tag> some text<tag>tag is starting here blabla and ends here</tag>
The output will be:
$ tac a | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p' | tac tag is starting here blabla and ends here
If like me, you don't have access to tac because your sysadmin won't play ball you can try:
grep pattern file | tail -1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With