raphy75
raphy75

Reputation: 99

How to color the output of awk depending on a condition

I have an input file test.txt containing the fallowing:

 a 1 34
 f 2 1
 t 3 16
 g 4 11
 j 5 16

I use awk to print only string 2 and 3:

awk '{print $2 " " $3}' test.txt

Is there a way to color only the second string of my output depending on a condition, if the value is higher than 15 then print in orange, if the value is higher than 20, print in red. It will give the same but colored:

1 34(red)
2 1
3 16(orange)
4 11
5 16(orange)

The input could contain many more lines in a different order.

Upvotes: 2

Views: 7691

Answers (3)

Etan Reisner
Etan Reisner

Reputation: 80931

This awk command should do what you want:

awk -v red="$(tput setaf 1)" -v yellow="$(tput setaf 3)" -v reset="$(tput sgr0)" '{printf "%s"OFS"%s%s%s\n", $1, ($3>20)?red:($3>15?yellow:""), $3, reset}'

The key bits here are

  • the use of tput to get the correct representation of setting the color for the current terminal (as opposed to hard-coding a specific escape sequence)
  • the use of -v to set the values of the variables the awk command uses to construct its output

The above script is tersely written but could be written less tersely like this:

{
    printf "%s"OFS, $1
    if ($3 > 20) {
        printf "%s", red
    } else if ($3 > 15) {
        printf "%s", yellow
    }
    printf "%s%s\n", $3, reset
}

Edit: Ed Morton correctly points out that the awk programs above could be simplified by using a color variable and separating the color choice from the printing. Like this:

awk -v red="$(tput setaf 1)" -v yellow="$(tput setaf 3)" -v reset="$(tput sgr0)" \
'{
    if ($3>20) color=red; else if ($3>15) color=yellow; else color=""
    printf "%s %s%s%s\n", $1, color, $3, reset
}'

Upvotes: 14

JuniorCompressor
JuniorCompressor

Reputation: 20015

You can do the following:

awk '{printf "%s ", $2}
     $3 > 15 {printf "\033[33m"}
     $3 > 20 {printf "\033[31m"}
     {printf "%s\033[0m\n", $3}' test.txt

Unfortunately, I don't know the orange ansi escape code...

Another approach:

awk -v color1="\033[33m" -v color2="\033[31m" -v reset="\033[0m" '
     $3 > 15 && $3 <= 20 {$3=color1 $3 reset}
     $3 > 20 {$3=color2 $3 reset}
     {print $2, $3}' test.txt

Upvotes: 3

repzero
repzero

Reputation: 8412

awk '{if($2>15 && $2<=20){$2="\033[1;33m" $2 "\033[0m"};if($2>20){$2="\033[1;31m" $2 "\033[0m"};print}' file

breakdown

($2>15 && $2<=20){$2="\033[1;33m" $2 "\033[0m"}  # if field 2>15 and =<20, then add colour code to field 2.

if($2>20){$2="\033[1;31m" $2 "\033[0m"} ## if field 2>20, then add colour code to field 2.

print #print line afterwards

Upvotes: 2

Related Questions