I have an app which generates some output:
$ my-app
[metadata] - [21:06:51 DBG] Some message 111 <s:Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware>
[metadata] - [21:06:52 DBG] Some message 222 <s:Microsoft.AspNetCore.Hosting.Diagnostics>
[metadata] - [21:06:52 ERR] Some message 223 <s:Microsoft.AspNetCore.Routing.Matching.DfaMatcher>
[metadata] - [21:06:54 DBG] Some message 333 <s:PocApi.MyApp.Foo>
I remove the [metadata] -
part of the output as follows:
$ my-app | sed -r 's/.*\] - *//'
[21:06:51 DBG] Some message 111 <s:Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware>
[21:06:52 DBG] Some message 222 <s:Microsoft.AspNetCore.Hosting.Diagnostics>
[21:06:52 ERR] Some message 223 <s:Microsoft.AspNetCore.Routing.Matching.DfaMatcher>
[21:06:54 DBG] Some message 333 <s:PocApi.MyApp.Foo>
Now, I wish to color code the output (i.e., encode with ANSI color codes) so that:
- The text inside and including
[
and]
is always grey. - The message on lines which contain
<s:PocApi
are yellow. - The message on lines which contain
DBG
are light grey. - The message on lines which contain
ERR
are red.
Note, the message is always between ]
and <
.
Any ideas how I might do this? Maybe printf
, but I don't see a way to do pattern matching. Thanks for the help.
Oh, and for what it's worth, my-app
is a long-running application that streams output.
CodePudding user response:
For test purposes:
$ cat input
[21:06:51 DBG] Some message 111 <s:Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware>
[21:06:52 DBG] Some message 222 <s:Microsoft.AspNetCore.Hosting.Diagnostics>
[21:06:52 ERR] Some message 223 <s:Microsoft.AspNetCore.Routing.Matching.DfaMatcher>
[21:06:54 DBG] Some message 333 <s:PocApi.MyApp.Foo>
One awk
idea:
while read -r line
do
echo "${line}"
sleep 2
done < input |
awk '
BEGIN { # foreground colors # background colors
red = "\033[1;31m" # 41m
green = "\033[1;32m" # 42m
yellow = "\033[1;33m" # 43m
blue = "\033[1;34m" # 44m
purple = "\033[1;35m" # 45m
reset = "\033[0m"
}
/DBG/ { msg_color=blue }
/<s:PocApi/ { msg_color=yellow }
/ERR/ { msg_color=red }
{ line=$0
pos=index(line,"]")
out=green substr(line,1,pos) reset " " msg_color
line=substr(line,pos 2)
pos=index(line,"<")
out=out substr(line,1,pos-2) reset substr(line,pos-1)
print out
}
'
This generates:
NOTES:
- assumes all lines start with a
[...]
string followed at some point by a left arrow (<
) - the
while read ... do < input |
is to simulate OP's long-running application that streams output to thesed ... | awk ...
pipeline - OP hasn't provided rules for what happens when 2 (or more) rules apply to the same line (eg, line contains both
DBG
and<s:PocApi
) so I've picked an arbitrary precedent (patterns matched later in script take precedence over patterns matched earlier in script) - assumes there's a single space before/after all messages and said spaces are not to be colorized
- color codes were derived from this wiki page; OP should be able to find additional colors with a general web search on something like
ansi color codes
; also keep in mind available colors can vary based on the terminal (type)
CodePudding user response:
Using sed
$ sed -E "s/.[^[]*([^]]*ERR])([^<]*)/$(tput setaf 8)\1$(tput sgr 0)$(tput setaf 9)\2$(tput sgr 0)/;\
/DBG][^<]*<s:PocApi/s/.[^[]*([^]]*])([^<]*)/$(tput setaf 8)\1$(tput sgr 0)$(tput setaf 11)\2$(tput sgr 0)/;\
/<s:PocApi/ ! {s/.[^[]*([^]]*DBG])([^<]*)/$(tput setaf 8)\1$(tput sgr 0)$(tput setaf 7)\2$(tput sgr 0)/}" input_file