Usually, grep is used for filtering lines based on a regexp pattern. Matching multiple patterns as a conditional OR is easy to apply using alternation. For example, grep -E 'bread|banana' matches lines containing either bread or banana.

However, conditional AND requires multiple grep commands or the use of lookarounds if PCRE feature is available. A simpler alternative is to use awk.

$ cat table.txt
brown bread mat cake 42
blue cake mug shirt -7
yellow banana window shoes 3.14

# line containing 'cake' but not 'at'
# same as: grep 'cake' table.txt | grep -v 'at'
# with PCRE: grep -P '^(?!.*at).*cake' table.txt
$ awk '/cake/ && !/at/' table.txt
blue cake mug shirt -7

# first field containing 'low' or the last field is less than 0
# not easy to construct a grep solution here due to field/numeric comparison
$ awk '$1 ~ /low/ || $NF<0' table.txt
blue cake mug shirt -7
yellow banana window shoes 3.14

Video demo:


info See my GNU AWK ebook if you are interested in learning about the awk command in more detail.