27.14 Compound Searches
You may recall that you can search for lines containing "this"
or
"that" using the
egrep
(
27.5
)
egrep 'this|that' But how do you grep for "this" and "that"? Conventional regular expressions don't support an and operator because it breaks the rule that patterns match one consecutive string of text. Well, agrep ( 28.9 ) is one version of grep that breaks all the rules. If you're lucky enough to have it installed, just use:
agrep 'cat;dog;bird' If you don't have agrep , a common technique is to filter the text through several grep s so that only lines containing all the keywords make it through the pipeline intact:
grep cat But can it be done in one command? The closest you can come with grep is this idea:
grep 'cat.*dog.*bird'
which has two limitations - the
words must appear in the given order, and they cannot overlap.
(The first limitation can be overcome using As usual, the problem can also be solved by moving beyond the grep family to the more powerful tools. Here is how to do a line-by-line and search using sed , awk , or perl : [2]
sed '/cat/!d; /dog/!d; /bird/!d'
Okay, but what if you want to find where all the words occur in the same
paragraph
?
Just turn on paragraph mode by setting
awk '/cat/ && /dog/ && /bird/ {print $0 ORS}' RS=
And if you just want a list of the
perl -ln0e 'print $ARGV if /cat/ && /dog/ && /bird/' (Notice that as the problem gets harder, the less powerful commands drop out.) The grep filter technique shown above also works on this problem. Just add a -l option ( 15.7 ) and the xargs command ( 9.21 ) to make it pass filenames through the pipeline rather than text lines:
grep -l cat ( xargs is basically glue used when one program produces output that's needed by another program as command-line arguments.) - |
|