*NIX Tricks

[grep] AND, OR, and “these” but NOT “those”

Posted in cli, grep by kousik on September 25, 2009

For grepping line-by-line in a file filename, I often find these very useful

Match pattern1 OR pattern2 in the same line:
$ grep -E 'pattern1|pattern2' filename

Match pattern1 AND pattern2 in the same line:
$ grep -E 'pattern1.*pattern2' filename
The above command searches for pattern1 followed by pattern2. If the order does not matter or you want to search them in either order, then use the follwoing
$ grep -E 'pattern1.*pattern2|pattern2.*pattern1' filename
The pipe enables the OR search which we saw earlier. Another option for this situation (i.e., AND search when the order is not important):
$ grep -E 'pattern1' filename | grep -E 'pattern2'
which basically greps the STDOUT of the first grep.

Match pattern1 AND pattern2, but NOT pattern3 in the same line:
$ grep -E 'pattern1.*pattern2' filename | grep -Ev 'pattern3'
when the order of the first two patterns is important. When that order is NOT important:
$ grep -E 'pattern1' filename | grep -E 'pattern2' | grep -Ev 'pattern3'

Match pattern1 OR pattern2, but NOT pattern3 in the same line:
$ grep -E 'pattern1|pattern2' filename | grep -Ev 'pattern3'

N.B. (1) grep -E may be replaced by egrep.  I used grep -E everywhere in this post assuming a general case of regular expressions as patterns. Lowercase -e is also used for regex, but this is more “basic” than -E which supports “extended” regex, e.g. regular expression metacharacters like +, ?, | and (). (2) The -v flag is for non-matching grep.

Tagged with: , , , , , , , , , ,

5 Responses

Subscribe to comments with RSS.

  1. avinc said, on April 18, 2011 at 8:48 AM

    very useful, Thank for sharing

  2. svet said, on June 21, 2011 at 1:14 AM

    thank you!!! very useful for newbie like me!!!

    • kousik said, on June 22, 2011 at 9:36 AM

      You are welcome :)

  3. yokmp said, on January 20, 2012 at 1:31 PM

    Match pattern1 but not 2:

    grep -o “pattern1[^NOT]”

    An ls -RA| grep -o “\./.*[^:]” will output all folders but not the files in them.
    And ls -RA| grep -o “\./.*[^:]“|sed s#’./’#$PWD/# will do the same but extends the path …

    • kousik said, on January 20, 2012 at 3:31 PM

      Very nice! Thanks!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.