Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you color lines that begin with string1 but do not end with string2

Tags:

grep

bash

sed

awk

perl

I run a weekly crontab that collects information and creates a log file.

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
HW_FILE="$(ls -t /home/user/hwinfo/|head -1)"

# List the Site name, hardware group, Redundancy or Health status', and the site divider
grep -i 'Site\|^\*\*\|^Redundancy\|^Health\|^##' /home/user/hwinfo/$HW_FILE
echo "/home/user/hwinfo/"$HW_FILE
exit 0

This is a sample output:

Accessing Site: site01
** FANS **
Redundancy Status : Full
** MEMORY **
Health : Ok
** CPUs **
Health : Ok
** POWER SUPPLIES **
Redundancy Status : Full
##########################################
Accessing Site: site02
** FANS **
Redundancy Status : Full
** MEMORY **
Health : Degraded
** CPUs **
Health : Ok
** POWER SUPPLIES **
Redundancy Status : Full
##########################################
Accessing Site: site03
** FANS **
Redundancy Status : Failed
** MEMORY **
Health : Ok
** CPUs **
Health : Ok
** POWER SUPPLIES **
Redundancy Status : Full
##########################################
/home/user/hwinfo/hwinfo_102217_034001.txt

Is there a way to cat / grep / sed / awk / perl / the current output so that any lines that begin with either Redundancy or Health, but don't end in Full or Ok, respectively, get colorized?

What I want to see is this

imgur link

I've tried piping the current output to | grep --color=auto \bRedundancy\w*\b(?<!Full)\|\bHealth\w*\b(?<!Ok) without success. Any assistance would be greatly appreciated.

like image 404
PCnetMD Avatar asked Jan 23 '18 21:01

PCnetMD


2 Answers

With any awk in any shell on any UNIX box:

awk -v on="$(tput setaf 1)" -v off="$(tput sgr0)" '$1~/^(Health|Redundancy)$/ && $NF!~/^(Full|Ok)$/{$0 = on $0 off} 1'  file

enter image description here

You should really use a more robust expression with string comparisons though rather than the current loose regexp:

awk -v on="$(tput setaf 1)" -v off="$(tput sgr0)" '
(($1=="Health") && ($NF!="Ok")) || (($1=="Redundancy") && ($NF!="Full")) { $0 = on $0 off }
1'  file
like image 168
Ed Morton Avatar answered Nov 16 '22 06:11

Ed Morton


Using GNU grep:

| grep -P --color=auto '^Redundancy.*(?<!Full)$|^Health.*(?<!Ok)$|$'

-P to use PCRE for lookbehind (which I don't think grep supports otherwise), |$ to make it output all lines. You need to use the lookbehind right before the line-end.

like image 7
ysth Avatar answered Nov 16 '22 05:11

ysth