Home > Enterprise >  grep/bash return exit1 if two words are not found [duplicate]
grep/bash return exit1 if two words are not found [duplicate]

Time:09-25

i use a command for generating a list to STDOUT. this list looks like:

12345     stable
678
231
123
testing
2323
12345678     next

what i want is having only a match if the word testing AND stable are both in this list. so currently i do is:

grep -e stable -e testing

but this also matches if only one string is in the list. so this produce exit0 also if one string is not there (which is not wanted) what i want is that grep has exit1 as code $? if not two strings/words are found. so i need a dedicated and search here.

so what i want in PSEUDOCODE:

IF BOTHWORDS are there then;
EXITCODE=0

otherwise
EXITCODE=1

do you have an idea how to solve?

CodePudding user response:

The problem is that (by default) grep is line-oriented. You want to search several lines as one block of text.

With GNU grep, use the -z option to delimit lines by the null-byte instead of newline.

Also, since both words must appear, your pattern has to be more complex:

produce_output() {
echo "12345     stable
678
231
123
testing
2323
12345678     next
"
}

# "stable" followed by "testing", or "testing" followed by "stable"
regex='(stable.*testing)|(testing.*stable)' 

produce_output | grep -q -E "$regex" && echo found || echo not found
# => not found

produce_output | grep -z -q -E "$regex" && echo found || echo not found
# => found

To get the exit status:

grep -z -q -E "$regex"
exitCode=$?

But you usually don't need to do that explicitly.


provides an alternate solution that is nicely readable:

produce_output | awk '/stable/ {s  } /testing/ {t  } END {exit !(s > 0 && t > 0)}'

CodePudding user response:

In the simplest case, assuming stable always occurs before next -

$: sed -n '/stable/,${ /next/q0; }; $q1;' file && echo found both || echo no match
found both

If they could be in reverse order, add a second scan with arguments switched.

$: sed -n '/stable/,${ /next/q0; }; /next/,${ /stable/q0; }; $q1;' file 

Sometimes it's easier to write your own logic.
It would be trivial to do in awk as well.

$: awk '/stable/{s  } /next/{n  } s&&n{exit 0} END { if(!(s&&n)){exit 1} }' file && echo found both || echo no match
  • Related