5

Below is extract output from my check script which I would like to print only hostname and error. If there is no error for host delete the entry of hostname too.
The logic I want to use is delete existing line if next line doesn't match "NOT OK"
May use awk or sed...any utility is good for pattern matching.

NSAS_HOST:d01-emsacssb01
NSAS_HOST:d01-emsacssb02
NSAS_HOST:emsacssbcon01
NOT OK main load processes
NOT OK 5.3% AXConfigurator
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.bak is not UP, but ifcfg-eth1.bak sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:emsacssb03
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:emsacsnb01
NSAS_HOST:emsacsnb02
NSAS_HOST:d02-emsacssb01
NSAS_HOST:d02-emsacssb02
NSAS_HOST:b2bcms01
NSAS_HOST:b2bcms02
NSAS_HOST:d02-b2bpgdb01
NOT OK bond0: device speed not determined
NOT OK bond1: device speed not determined

Expected result:

NSAS_HOST:emsacssbcon01
NOT OK main load processes
NOT OK 5.3% AXConfigurator
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.bak is not UP, but ifcfg-eth1.bak sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:emsacssb03
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:d02-b2bpgdb01
NOT OK bond0: device speed not determined
NOT OK bond1: device speed not determined

Basically:
1. search for term NSAS_HOST
2. check next line for NOT OK. If it exists print lines until we reach the next NSAS_HOST
3. If NOT OK doesn't exist just delete the NSAS_HOST line

1

3 Answers 3

4

You could use sed for this job:

sed '/NSAS_HOST/{$d;N;/\n.*NOT OK/!D;}' infile

This just pulls in the Next line on each line that matches NSAS_HOST (except if on the la$t line when it deletes the pattern space). If the 2nd line in the pattern space does not match NOT OK, it Deletes up to the newline (that is, it deletes the 1st line in the pattern space) and restarts the cycle.

2
  • @Wildcard - that doesn't work either (I could explain why but it's too long)... I usually don't use n and h/H together, so I would probably run sed '/NSAS_HOST/{h;d;};/NOT OK/{x;/NSAS_HOST/G;//!x;}' Nov 8, 2016 at 0:38
  • My alternate approaches didn't work correctly; I'm removing them. Thanks for pointing out the interaction between -n and the n command.
    – Wildcard
    Nov 8, 2016 at 0:41
0

with sed :

sed -ne '/NSAS_HOST/{N;/NOT OK/{p}};/NSAS_HOST/!p' FILE 

OUTPUT:

NSAS_HOST:emsacssbcon01
NOT OK main load processes
NOT OK 5.3% AXConfigurator
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.bak is not UP, but ifcfg-eth1.bak sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:emsacssb03
NOT OK eth0.orig is not UP, but ifcfg-eth0.orig sets ONBOOT=yes
NOT OK eth1.orig is not UP, but ifcfg-eth1.orig sets ONBOOT=yes
NSAS_HOST:d02-b2bpgdb01
NOT OK bond0: device speed not determined
NOT OK bond1: device speed not determined
1
  • 1
    this logic has a problem. how about like first two NSAS_HOST lines and then NOT OK.
    – mug896
    Jan 20, 2017 at 17:01
0

It's so easy in pure grep:

grep --no-group-separator -B1 ^"NOT OK" log 
2
  • 2
    1. This works with the input sample (that is, all lines match either NSAS_HOST or NOT OK) but if there are other lines (that need to be preserved) this won't print them. 2. You don't need the second grep: use --no-group-separator Nov 7, 2016 at 23:55
  • Wow, "hidden" feature! It isn't in the manual. Nov 7, 2016 at 23:57

You must log in to answer this question.

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