Reputation: 2054
I am capturing output from a command/script in a variable. The output is essentially a block of text. In the context of this question, let us consider this:
output='In java, both Errors and Exceptions are the subclasses of some/long/path/to/file.java class. Error refers to an illegal operation at line=23 and executed by app=client
Problem: I like to colorize parts of the message before writing to stdout. I managed to find a way but makes sense / works just for one substitution.
color_end=$'\33[0m'
color_red=$'\33[31m'
echo "${output//line=/${color_red}LINE=$color_end}"
I like to match and colorize other parts (say <filename>.java
, app=
) too. I tried using regex in the variable substitution above but none of these work. Getting syntax errors or the like.
echo "${output//(line=|app=)/${color_red}$1$color_end}"
Tried using sed
but 1) colors are interpreted so when writing to stdout 2) gets a bit hairy with regex pattern.
What is the best way to achieve this?
FWIW, it is only one color for all the matched parts. Not different colors for different matched parts.
Upvotes: 0
Views: 121
Reputation: 5231
I would do it like this:
# Only set colors if printing to a terminal
test -t 1 && t_red1=$'\033[31m' t_01=$'\033[0m'
# List here the regexes to highlight
echo "$output" |
sed -E 's/[[:alnum:]_]+=|[^[:space:]]+\.java'/"$t_red1&$t_01/g"
BASH_REMATCH
, but sed
is simpler, and probably more efficient.test -t 1
ensures the variables are only set if stdout (fd 1) is a terminal, which is important.t_red1
refers to terminal control sequence for color red, on file descriptor 1.t_
distinguishes from other variables, and the trailing fd number allows for separate control sequences per file descriptor (each of which may or may not be a terminal).test -t 2 && t_red2=$'\033[31m' t_02=$'\033[0m'
.Upvotes: 1