Reputation: 763
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:
[
and ]
is always grey.<s:PocApi
are yellow.DBG
are light grey.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.
Upvotes: 1
Views: 312
Reputation: 34244
To simulate the output from my-app
:
$ cat input
[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>
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,"] - ") # these 2 lines replace
line=substr(line,pos+4) # the current sed script
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:
^[...] - [...]
followed at some point by a left arrow (<
)while read ... do < input |
is to simulate OP's program output being piped to awk
(ie, my-app | awk ...
)DBG
and <s:PocApi
) so I've picked an arbitrary precedent (patterns matched later in script take precedence over patterns matched earlier in script)ansi color codes
; also keep in mind available colors can vary based on the terminal (type)Upvotes: 4
Reputation: 11217
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
Upvotes: 2