Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I am using a command like this to find files with the word 'term' in them:

grep -l term *

But I now want to be able to find files which have two different words in them (let's call them termA and termB) - not necessarily on the same line. I want to find files with both terms in, not just files that have either term.

Now I could write a cumbersome bash script for this, but does grep, egrep, awk, sed or anything else have a tool that can help me?

Thanks in advance.

share|improve this question
add comment

3 Answers

up vote 4 down vote accepted

If your files contain no null bytes

In this case, you can use grep alone:

grep -Plz "termA.*termB|termB.*termA" *

How it works:

  • The Perl Compatible Regular Expressions termA.*termB and termB.*termA search for strings which have both terms in it.

  • The combined PCRE termA.*termB|termB.*termA matches all strings containing both terms.

  • Finally, the -z switch makes data lines end in null bytes instead of newlines.

By the way, there's no need to use -P. If you prefer to continue using POSIX Basic Regular Expressions, the syntax is similar:

grep -lz "termA.*termB\|termB.*termA" *

If your files contain null bytes

In this case, you'll need auxiliary tools:

(grep -l termA * ; grep -l termB *) | sort | uniq -d

How it works:

  • grep -l termA * ; grep -l termB * displays all files containing either of the terms. Files that contain both terms will be displayed twice.

  • sort sorts the output.

  • uniq -d only displays duplicate lines (required lines to be sorted).

share|improve this answer
    
Thanks - this is looking for the terms to be on the same line though. –  Peter Howe Jul 11 '12 at 13:25
    
Sorry, I overlooked that requirement. I've updated my answer. –  Dennis Jul 11 '12 at 13:42
    
Tnanks Dennis. The uniq -d was what I needed. –  Peter Howe Jul 11 '12 at 14:51
add comment

grep supports regular expressions as far as I know. I use the following syntax to search multiple terms:

    grep 'termA\|termB' /i/am/a/path

you do need to use the escape character '\' before each '|' but with that I bvelieve you can use as many search strings as you want

share|improve this answer
    
Sorry, I've clarified it in the question now, but I'm after a list of files with both terms in. This would give me a list of files with either in. –  Peter Howe Jul 11 '12 at 13:03
add comment

You can use either the -e or -f options to search for multiple expressions (from man grep):

    -e PATTERN, --regexp=PATTERN
          Use  PATTERN  as  the  pattern.   This  can  be  used to specify
          multiple search patterns, or to protect a pattern beginning with
          a hyphen (-).  (-e is specified by POSIX.)

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

So you would use this as:

$ grep -e termA -e termB *
share|improve this answer
    
Thanks. Not quite what I'm after. Your example (with -l to display the files) will give me files tat have either termA or termB in them. I want a list of files that have both terms in. –  Peter Howe Jul 11 '12 at 13:00
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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