Complex coloring in script

My script prints lines in which the entire line may be colored, and portions may also be colored. e.g.

Consider this to be one line:

$red some text in red $yellow abcd $end_yellow red text 1234 $blue some text $end_blue more red text $end_red

So using sed, I may based on condition 1, color the entire line red, and then based on other patterns, color portions in various colors.

I am aware of how to start coloring. However, the command to end coloring, ends *all* coloring, instead of switching off the existing color. So i cannot embed colors within other colors.

I've searched high and low but can't find anything -- any ideas.

e.g. of color switching off:

COL_NORM="$(tput setaf 9)"

or COL_NORM=$'\033[0m'

(You can refer this page for ANSI terminal codes)

Hi,

Try this....

print "\033[32m RED \033[0m \033[34m BLUE \033[\0m \033[32m GREEN \033[0m" ;

Nope, i am not looking for a hard coded solution.
You are missing the part there are red portions throughout the line.

My code is like:

items = @( echo "$items" \
| sed "s/PATT1/${COLOR_RED}PATT1${COLOR_NONE}/g; \
...
/(A)/s/.*/$COLOR_YELLOW & $COLOR_NONE/;
...

)

If some patterns are found, only those patterns are printed in a color.
For other patterns, the entire line is printed in a color.

So you can have a red line with some words in blue or white etc.

However, since the code for closing a color closes all colors, so the rest of the line comes uncolored.

\033[0m - removes all color attributes. I am looking for something that will only switch off a given color, so the rest of the line can continue in the old color.

Its a bit like:
$red textaaa $green textggg $end_green textbbb textcc $end_red

so textbbb continues in red.

I don't know of a way to turn off specific colors.

But I've got this to work on my dtterm (hp-ux using posix shell)

 
RED="$(tput setaf 1)"
BLU="$(tput setaf 4)"
YEL="$(tput setaf 3)"
OFF="$(tput sgr0)"
 
# given the line "Patti is great" I want to set the whole line to $RED 
#because it has the pattern "Patti" in it, but I want the word "is" to be
#yellow".
 
#variable DEF is set on the fly to the full line color.
 
#$BLU output just to establish I'm setting DEF properly
echo "Patti is great" | (DEF=${BLU};sed -ne s/Patti.*/${DEF}\&${OFF}/p)
 
#RED output
echo "Patti is great" | (DEF=${RED};sed -ne s/Patti.*/${DEF}\&${OFF}/p)
 
#FINAL output - RED 'Patti' YEL 'is' RED 'great'
echo "Patti is great" | (DEF=${RED};sed -ne s/Patti.*/${DEF}\&${OFF}/p) | sed -ne s/is/${YEL}\&${DEF}/p

You need the parenthesis to group the assignment to DEF and the sed statement into the same STDIN.

Basically, by setting the variable DEF on the fly, you can create the default color for the whole line. Then instead of turning yellow "OFF" after the word 'is' you just turn red back on with DEF.

This works for me, hopefully I didn't put a typo in. :wink:

---------- Post updated at 05:44 PM ---------- Previous update was at 05:17 PM ----------

Actually, further testing proved it didn't work I had DEF set in my environment, and when I unset it, I got spurious results, however the followig did work:

echo "Patti is great" | (DEF=${RED}; sed -ne s/.*Patti.*/${DEF}\&${OFF}/ -e s/is/${YEL}\&${DEF}/p)

I put the assignment to DEF and all seds into the same process using multiple -e's to separate out the sed patterns, and printing only on the last pattern of the line.

Try...

(
  echo "redline etc etc blueword etc etc"
  echo "etc etc blueword etc etc"
) |\
  awk 'BEGIN {
             RED  = "\033[31m"
             BLUE = "\033[34m"
             OFF  = "\033[0m"
       }
       {
             NORM = OFF
       }
       /redline/ {
             $0 = RED $0 OFF
             NORM = RED
       }
       {
             gsub(/blueword/, BLUE "&" NORM)
             print $0
       }'

Thanks a lot, and much thanks for the awk script, Ygor.

I was also thinking along these lines in my sleep :wink:

  1. First color the entire line.
  2. Use the line color, as the OFF color for other colors
  3. Now color individual words.

Happy New Year to you all.