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< |