Exclude multiple lines using grep

Hi,
I'm working on a shell script that reports service status on a database server.
There are some services that are in disabled status that the script should ignore and only check the services that are in Enabled status.

I output the service configuration to a file and use that information to loop through the services. Unfortunately im not able to exclude the service that is in Disabled status.

Here's the content of the file -

Service name: Bot_Serv1
Service is disabled
Preferred instances: botqa2,botqa3

Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3


Each service configuration is separated by a blank line. As you can see the first service is in Disabled status and the 2nd service is Enabled .

How do i get the content of the file, excluding the configuration details for the Disabled service. Im looking to grep the file and output should be the following -

Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3

grep doesn't do that, you need a language which can remember things, like awk.

RS="" tells awk to process text in blocks separated by two newlines.

!/Service is disabled/ prints every block which doesn't contain "Service is disabled".

$ awk -v RS="" -v ORS="\n\n" '!/Service is disabled/' data

Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3

$
1 Like

Thank you very much, that works perfectly. Interesting to know how powerful is awk. shall experiment with it :slight_smile:

Thanks again.

awk '/Service is enabled/{print s;print;getline;print $0}{s=$0}'  input.txt

Hi.

A version of grep , context grep, cgrep approach:

#!/usr/bin/env bash

# @(#) s1       Demonstrate extract paragraph, cgrep.
# Source for cgrep:
# https://sourceforge.net/projects/cgrep/ (verified 2016.09.28)

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C

FILE=${1-data1}
E=expected-output.txt

pl " Input data file $FILE:"
cat $FILE

pl " Expected output:"
cat $E

pl " Results:"
cgrep -D -1 +w='' "enabled" $FILE |
tee f1

pl " Verify results if possible:"
C=$HOME/bin/pass-fail
[ -f $C ] && $C || ( pe; pe " Results cannot be verified." ) >&2

exit 0

producing:

$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.6 (jessie) 
bash GNU bash 4.3.30

-----
 Input data file data1:
Service name: Bot_Serv1
Service is disabled
Preferred instances: botqa2,botqa3

Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3


-----
 Expected output:
Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3


-----
 Results:
Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3


-----
 Verify results if possible:

-----
 Comparison of 4 created lines with 4 lines of desired results:
 Succeeded -- files (computed) f1 and (standard) expected-output.txt have same content.

The heart of this solution is:

cgrep -D -1 +w='' "enabled" 

search for enabled, copy one line before, and all lines after until an empty line occurs.

Best wishes ... cheers, drl

Gnu grep has -C option.

bash-3.2$ cat t.txt
Service name: Bot_Serv1
Service is disabled
Preferred instances: botqa2,botqa3

Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3


bash-3.2$ grep -C1 "Service is enabled" t.txt
Service name: Bot_Serv2
Service is enabled
Preferred instances: botqa2,botqa3
1 Like