23

Is there a simpler way to do this? grep -v foo file | grep -v bar

There're probably very elegant ways to do it with egrep, but how to go with plain old grep?

EDIT: grep -v 'foo\|bar' file seems to work only with GNU grep. I'm on Solaris. Any solution for that?

2
  • Strange question because in the first example you are doing AND match, and in the second you are doing OR match. The outcome will be the same only in very specific conditions. Nov 10 '12 at 7:40
  • 1
    No not really. In the second example, the -v flag is a negation. not(A or B) == not(A) and not(B)
    – rahmu
    Nov 10 '12 at 10:02
34

You can have multiple tests in a single grep command by passing each expression with a -e argument instead of as the first non-option argument as you normally see:

$ grep -v -e foo -e bar file

That says the same thing your command does: print lines from file that contain neither "foo" nor "bar".

Keep in mind that removing -v completely inverts this; it changes the logical operation, too! You get all lines that contain "foo" or "bar".

19

grep -Ev 'word1|word2' should work just fine

3
  • As an alternative you can use egrep and drop the backslash for the pipe character: egrep -v 'word1|word2
    – OldTimer
    Aug 26 '11 at 10:46
  • Turns out this does not work with the Solaris grep. I installed the GNU grep and worked perfectly. I'm going to edit my question to make it Solaris specific.
    – rahmu
    Aug 26 '11 at 10:52
  • 2
    @rahmu \| is a GNU grep extension, but you can achieve the same thing in a portable way with -E and the | operator. Aug 26 '11 at 22:42
1

You could also use curly braces for parameter expansion:

grep -v -e{foo,bar}

which effectively is the same as:

grep -v -e foo -e bar

(I don't have enough reputation points to add this as a comment)

0

On Solaris 11.4, if you set your PATH variable correctly to pick up the command line tools that are slightly more usable than the default set, then you would be able to use

grep -E -v 'foo|bar' file

You get this more capable grep as your default grep if you set your PATH like so:

PATH=$(/usr/xpg6/bin/getconf PATH):$PATH

This would add the following paths to the front of your existing PATH variable's value, on a default Solaris 11.4 system:

/usr/xpg6/bin:/usr/xpg4/bin:/usr/bin:/opt/developerstudio12.5/bin:/opt/solarisstudio12.4/bin

See also man standards on a Solaris system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.