8

I know that I can search for multiple patterns like so

    grep -e 'pattern1|pattern2' file

and I can invert the grep search like so

    grep -v 'pattern' file

but is there a way I can grep for one pattern while simultaneously doing an inverse grep for another?

    grep -e 'pattern I want' -v 'pattern I do not want' file
codeforester
  • 39,467
  • 16
  • 112
  • 140

2 Answers2

10

You may use awk as an alternative:

awk '/pattern I want/ && !/pattern I do not want/' file
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

Assuming suitably quoted patterns,

 sed -n "/$pat1/ { /$pat2/ d; p; }" file

-n tells sed not to print unless explicitly requested.
/$pat1/ { ... } says on lines matching $pat1, execute the commands in the braces.
/$pat2/ d; says on lines with $pat2, delete, which automatically cycles to the next line of input and ignores any more commands for this line, skipping the p. If it does not see $pat2, the d doesn't fire and proceeds to...
p means print the current line.

My example:

$: grep '#if ' dcos-deploy.sh
#if   (( ${isPreProd:-0} ))
#if [[ "$target_mesosphere_cluster" != CDP ]]

$: pat1="^#if "
$: pat2="\\[\\["

$: sed -En "/$pat1/ { /$pat2/ d; p; }" dcos-deploy.sh
#if   (( ${isPreProd:-0} ))
Paul Hodges
  • 13,382
  • 1
  • 17
  • 36