2

I have a variable var. Want to print the lines after Code: in blue (but with the line specifying Code: removed), whilst the rest is printed in green. Am using a bash script that calls awk to do the variable processing running ubuntu.

sgr="$( tput sgr0 )"
grn="$( tput bold; tput setaf 34 )"
blu="$( tput bold; tput setaf 39 )"

var="
 Description
 Code:
  for i in {1..72..1}; do shft+=\" \"; done
 
 Details"

printf '%s\n' "$var"  \
 | awk -v kb="$blu" -v kg="$grn" -v rst="$sgr"  \
     '{ codefound = 0
        fm="%s%s%s\n"
        if (codefound) { printf(fm, kb, $0, rst) }
        else { printf(fm, kg, $0, rst) }
      }'

How can one define the colours in awk itself ?

I want to produce the following (the # used to describe the foreground colour of the text):

 Description  # green
   for i in {1..72..1}; do shft+=" "; done  # blue
 
 Details  # green
2

3 Answers 3

3

Based heavily on the answer at using-awk-to-color-the-output-in-bash, this might be what you want for this and any similar situations where you need to change, potentially multiple, foreground and/or background colors:

$ cat tst.awk
BEGIN {
    split("BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE",tputColors)
    for (i in tputColors) {
        colorName = tputColors[i]
        colorNr = i-1

        cmd = "tput setaf " colorNr
        fgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
        close(cmd)

        cmd = "tput setab " colorNr
        bgEscSeq[colorName] = ( (cmd | getline escSeq) > 0 ? escSeq : "<" colorName ">" )
        close(cmd)
    }

    cmd = "tput sgr0"
    colorOff = ( (cmd | getline escSeq) > 0 ? escSeq : "<sgr0>" )
    close(cmd)

    fgColor = dfltFgColor = "GREEN"
}

/Code:/ { fgColor = "BLUE"; next }
!NF { fgColor = dfltFgColor }
{ print fgEscSeq[fgColor] $0 colorOff }

enter image description here

If you'd rather not use tput to define colors then see searching-and-coloring-lines-by-awk-or-other-method for how to use escape sequences instead.

2
  • I really want to use specific numeric values for the colours sgr="$( tput sgr0 )" ; wht="$( tput bold; tput setaf 15 )" ; blu="$( tput bold; tput setaf 39 )".
    – Vera
    Commented Feb 11, 2023 at 16:14
  • 1
    Then also add that to your question. Again, don't add information in comments where it could be missed.
    – Ed Morton
    Commented Feb 11, 2023 at 16:50
2

To colorizing a line with ANSI escape codes in awk say a line containing string "WORD", you can do:

printf '%s\n' "$var" |
awk '
BEGIN{
       blue ="\033[1;44m"
       rst  ="\033[0m"
}
/WORD/{ $0=blue $0 rst }1'

The code for your need would be:

printf '%s\n' "$var" |
awk '
BEGIN{
       green ="\033[1;42m"  #default output color
       blue  ="\033[1;44m"
       rst   ="\033[0m"
}
/Code:$/  { Clr=1; next }  # active the blue colored ouptut
/Details$/{ Clr=0 }        # disable the blue colored output

{ print (Clr? blue : green) $0 rst }'

see ANSI escape code

1
  • Not all devices use ANSI codes, that's the reason why tput and the related termcap/terminfo exist. Commented Feb 12, 2023 at 8:22
1

I wouldn't use awk for this, I would just use sed and printf:

#!/bin/bash

var="
 Description
 Code:
  for i in {1..72..1}; do shft+=' '; done
 
 Details"

sgr="$( tput sgr0 )"
grn="$( tput bold; tput setaf 34 )"
blu="$( tput bold; tput setaf 39 )"

printf "%s" "$grn"; sed -E "s/Code:/$blu/; s/^( *Details.*)/${grn}\1${sgr}/" <<<"$var"; 

This produces:

Screenshot of the terminal showing the output of the command in color

If you insist on awk, something like this would work:

#!/bin/bash
var="
 Description
 Code:
  for i in {1..72..1}; do shft+=' '; done

 Details"

sgr="$( tput sgr0 )"
grn="$( tput bold; tput setaf 34 )"
blu="$( tput bold; tput setaf 39 )"

awk -v sgr="$( tput sgr0 )" \
    -v grn="$( tput bold; tput setaf 34 )" \
    -v blu="$( tput bold; tput setaf 39 )" \
'BEGIN{ printf "%s", grn }
{
  if(/Code:/){ printf "%s", blu }
  else if(/Details/){ printf "%s%s%s\n",grn, $0, sgr }
  else { print }
}' <<<"$var"; 
5
  • For the awk solution, it still prints Code:. I also want to have blue foreground on the consecutive lines until a blank line occurs.
    – Vera
    Commented Feb 11, 2023 at 13:58
  • One does not match for Details, Once one gets the first blank line, one changes to green colour, until another match for Code:.
    – Vera
    Commented Feb 11, 2023 at 15:02
  • @Gibran please add that information to your question, don't add it as a comment where it can be missed.
    – Ed Morton
    Commented Feb 11, 2023 at 15:05
  • @Gibran the awk one doesn't print Code:, are you sure you copied it exactly? Can your file have Windows line endings perhaps? And the simpler one does match Details, at least on my machine, so again, maybe Windows line endings?
    – terdon
    Commented Feb 11, 2023 at 17:33
  • @terdon the OP isn't saying your code doesn't match Details, they're saying it does match Details but it shouldn't, it should match an empty line.
    – Ed Morton
    Commented Feb 13, 2023 at 12:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .