View Single Post

   
  #3 (permalink)  
Old 02-15-2008, 05:44 PM
Bela Lubkin
 
Posts: n/a
Default Re: help with grep looking for cats and dogs

Kevin Fleming wrote:

> I've been searching high and low for how to grep for two different
> strings at once, and I'm not sure that it can be done. Ideas?
> I've got a bunch of files and I'm searching for ones that have both the
> word "cat" and "dog" in them, not necessarily on the same line.
> I've tried using something like this:
>
> find /tmp -exec grep -q -E "cat" {} \; -print
>
> but I can't seem to do both cat and dog at the same time.
>
> find /tmp -exec grep -q -E "cat.\dog" {} \; -print
>
> this is closer, but it only works if cat and dog are on the same line.


Start by learning how to search a single file for multiple strings; get
rid of the `find` part of this equation.

You are using `grep -E`, which is the newfangled name for `egrep`.
Either will work and I'm going to use `egrep` here because I think it
shows the differences more clearly. I'll search /etc/termcap and I'll
use "cat" and "man" because both of those strings appear in
/etc/termcap.

So. Regular `grep` (and `egrep` and `fgrep`) will search for multiple
expressions given as multiple lines in the search string:

$ grep 'cat
man' /etc/termcap

`egrep` adds alternation:

$ egrep 'cat|man' /etc/termcap

This should produce the same results, but (in the case of OSR5)
alternation is a lot slower. That's due to an ancient library bug which
was never fixed in OSR5. I don't know if OSR6 is better. Because of
this bug, I always use the separate-lines syntax for simple alternation.
For complex alternation: "(cat|man).*bites.*(rat|dog)", I use the '|'
syntax and live with the lame performance.

Putting `find` back in the mix:

$ find /tmp -exec grep -l 'cat
dog' {} \;

`grep -l` means "print only the names of matching files". This should
have the same effect you were trying to get with `grep -q` followed by
"-print", but seems more direct to me.

>Bela<

Reply With Quote