When the text directly contained color code for example:
a="\033[0;31mRED\033[0m"
echo -e $a
The terminal had no problem colorizing the text in red. But when I modified the color code indirectly:
#!/bin/bash
# define color mappings
declare -A colors=(
['r']='\033[0;31m' # Red (escaped for sed/printf)
['reset']='\033[0m' # Reset color
)
# Sample text
t="abc def [ghi] jkl
nmo [ttt] dfd
and more"
# colorize all [...] in red
echo -e "$t" | sed "s/\(\[[^]]*\]\)/\\${colors[r]}\1\\${colors[reset]}/g"
The result was
abc def \033[0;31m[ghi]\033[0m jkl
nmo \033[0;31m[ttt]\033[0m dfd
and more
The terminal did not colorize [...]s with red color at all but showed the raw color codes. It seems like the problem is related to the timing of variable expansion of some sort.
The problem is not in variable expansion. The problem is you need echo -e to interpret the colour codes, but you run echo -e only for the original string. You then insert the colour codes, but this doesn't go through echo -e anymore. So, one way is to add it:
echo -e $(echo "$t" | sed "s/\(\[[^]]*\]\)/\\${colors[r]}\1\\${colors[reset]}/g" )
You can also store directly the colour codes, not their escaped variant. Then, you can directly output them without needing -e:
declare -A colors=(
['r']=$'\033[0;31m' # <- See the dollar sign?
['reset']=$'\033[0m' # <- It interprets the escape sequences.
)
The rest of the script can stay as it was, but you don't need -e for the output:
echo "$t" | sed "s/\(\[[^]]*\]\)/\\${colors[r]}\1\\${colors[reset]}/g"