Reputation: 401
I've read through the man page of grep and tried few things, none of them worked, at least not for me.
I want to extract a good readable line while tailing a log. This is a generic line in a log file I want to beautify:
26 Jan 2018 08:32:29,309 [TEXT] (myService-0) long.text.I.dont.care.about.but.is.different.in.every.line: [OTHERTEXT] Text im actually interested in
What I want is this:
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
I know that with grep -o -e ".*\[TEXT\]"
I get the first part, and with grep -o -e "\[OTHERTEXT\].*"
, I get the second part.
But this is not displayed on one line, also not if I combine it into grep -o -e ".*\[TEXT\]" -e "\[OTHERTEXT\].*"
[TEXT]
and [OTHERTEXT]
always are there and are my 'separators', so can be used to support extracting the parts I need.
I initially thought I could use grep -o -e "(.*\[TEXT\]).*(\[OTHERTEXT\].*)"
and then somehow use the matching groups $1
and $2
, but either I don't see it or there is no way to do so.
Is there a way to achieve what I want?
Preferred is using grep
(simply because I want to learn more about it), but if that is not possible then awk
or sed
are fine as well, it just has to be usable with a tail -f
.
And I'm also open to other approaches to get to that point, so let me know what ways exist to get there.
Thanks, Tobias
Upvotes: 3
Views: 2494
Reputation: 37404
Using awk you could replace everything between ]
and [
with ] [
:
$ awk 'sub(/\].*\[/,"] [")' file
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
Upvotes: 1
Reputation: 1675
You probably need sed for doing what you want:
sed -E 's/(.*\[TEXT]).*(\[OTHERTEXT])/\1 \2/'
But to answer to your question about how to show matches in grep, yes it is possible with the option -o
. This option will show only matched parts of the matching line. Nevertheless, if you use
grep -o -e ".*\[TEXT\]" -e "\[OTHERTEXT\].*"
you will get your matched parts but in separate lines.
Another possibility could be to use look-ahead and look-behind expressions, but it cannot work in your case.
Upvotes: 0
Reputation: 23667
you can do that with perl
$ # note that this will print empty lines when no match is found
$ perl -lne 'print /(.*\[TEXT\] ).*(\[OTHERTEXT\].*)/' ip.txt
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
$ # you can avoid empty lines by checking for match first
$ perl -lne '/(.*\[TEXT\] ).*(\[OTHERTEXT\].*)/ && print $1,$2' ip.txt
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
since you are processing tail -f
output, you might need buffering control, see How to 'grep' a continuous stream? for example
Upvotes: 0
Reputation: 728
pipe your grep into
<your grep> | sed "s/(myService-0).*[OTHERTEXT]/(myService-0)[OTHERTEXT]/"
Upvotes: 0
Reputation: 785108
You can use sed
:
sed -E 's/(\[TEXT]).*(\[OTHERTEXT])/\1 \2/' file.log
26 Jan 2018 08:32:29,309 [TEXT] [OTHERTEXT] Text im actually interested in
This sed
matches a pattern between [TEXT]
and [OTHERTEXT]
and captures them in 2 groups. In replacement it puts those markers back using back-refrences \1 \2
Upvotes: 4