Can you colorize specific lines that are grepped from a file?

Viewed 385

I run a weekly CRONTAB that collects hardware info from 40+ remote servers and creates a weekly log file on our report server at the home office. I have a script that I run against this weekly file to output only specific status lines to my display.

#!/bin/sh

# store newest filename to variable
DD_FILE="$(ls -t /home/user/ddinfo/|head -1)"

# List the site name, disk ID (virtual & physical), Status and State of each ID, Failure Prediction for each physical disk, and the site divider
grep -w 'Site\|^ID\|^State\|^Status\|^Failure Predicted\|^##' /home/user/ddinfo/$DD_FILE
echo "/home/user/ddinfo/"$DD_FILE
exit 0

This is a sample output:

Accessing Site: site01
ID                            : 0
Status                        : Ok
State                         : Ready
ID                              : 0:0:0
Status                          : Ok
State                           : Online
Failure Predicted               : No
ID                              : 0:0:1
Status                          : Ok
State                           : Online
Failure Predicted               : No
################################################
Accessing Site: site02
ID                            : 0
Status                        : Ok
State                         : Ready
ID                              : 0:0:0
Status                          : Non-Critical
State                           : Online
Failure Predicted               : Yes
ID                              : 0:0:1
Status                          : Ok
State                           : Online
Failure Predicted               : No
################################################

Is there a way to cat / grep / sed / awk / perl / this output so that any lines that end with either Critical or Yes, get colorized?

5 Answers

With GNU grep:

grep --color -E ".*Yes$|.*Critical$|$" file

You could try , a very nice alternative to grep:

% ack '(Critical|Yes)$' file
# Or to colorize the whole line:
% ack '(.*(Critical|Yes))$' file

See Beyond grep

Or if you want to see all lines and only colorize specific ones:

use Term::ANSIColor qw/ colored /;
while (<$fh>) {
    s/(.*)(Critical|Yes)$/colored(["yellow bold"], $1.$2)/e;
    print;
}

To see all lines but have the lines that end in Critical or Yes colorized, try:

awk -v on="$(tput smso)" -v off="$(tput rmso)" '/(Critical|Yes)$/{$0=on $0 off} 1' logfile

This uses tput to create codes suitable for your terminal. For demonstration purposes, I chose the smso/rmso to set and reset the "standout mode." You can use any other feature that tput supports.

Variation

If we want the text in red instead of "standout mode":

awk -v on="$(tput setaf 1)" -v off="$(tput sgr0)" '/(Critical|Yes)$/{$0=on $0 off} 1' logfile

tput setaf 1 is the code to create red. (In tput, red is 1, green is 2, etc.). tput sgr0 is the code to turn off all attributes.

How it works

  • -v on="$(tput smso)" -v off="$(tput rmso)"

    This defines two awk variables, on and off that turn on and turn off whatever color effect we prefer.

  • /(Critical|Yes)$/{$0=on $0 off}

    For any line that ends with Critical or Yes, we add the on code to the front of the line and the off code to the end.

  • 1

    This is awk's cryptic shorthand for print-the-line.

You could use Term::ANSIColor module of Perl:

... | perl -pne 'BEGIN { use Term::ANSIColor } /: (Yes|Critical)$/ && { $_ = color("red") . "$_" . color("reset") }'

Thank you for all of your responses. I ended up piping the original grep results to another grep | grep --color=auto '.*\(Yes\|Critical\).*\|$' and got the colorized results I wanted:

grep -i 'site\|^ID\|^State\|^Status\|^Failure Predicted\|^##' /home/user/ddinfo/$DD_FILE | grep --color=auto '.*\(Yes\|Critical\).*\|$'

This the new sample output:

Sample Output

Related