0

I'm trying to find a better way to determine which files in a given directory contain all of a given set of search strings. The way I'm currently doing it seems awkward.

For example, if I want to find which files contain "aaa", "bbb", "ccc", and "ddd" I would do:

grep -l "aaa" * > out1 grep -l "bbb" `cat out1` > out2 grep -l "ccc" `cat out2` > out3 grep -l "ddd" `cat out3` > out4 cat out4 rm out1 out2 out3 out4 

As you can see, this seems clumsy. Any better ideas?

EDIT: I'm on a Solaris 10 machine

1
  • 1
    At least in bash, ` cat out1 ` is more simply written as $(<out1) (and it doesn't have to invoke cat). Commented Jan 28, 2013 at 18:53

2 Answers 2

1

You can use xargs to chain the grep calls together:

grep -l "aaa" * | xargs grep -l "bbb" | xargs grep -l "ccc" | xargs grep -l "ddd" 
Sign up to request clarification or add additional context in comments.

Comments

1

something along this may help:

for file in * ; do matchall=1 for pattern in aaa bbb ccc ddd ; do grep "$pattern" "$file" >/dev/null || { matchall=0; break ; } done if [ "$matchall" -eq "1" ]; then echo "maching all : $file" ; fi done 

(you can add patterns by replacing aaa bbb ccc ddd with something like $(cat patternfile))

For the ones interrested : it 1) loop over each file, and 2) for each file: it assumes this will match all patterns, and loops over the patterns: as soon as a pattern doesn't appear in the file, that pattern loop is exited, the name of that file is not printed, and it goes to check the next file. ie, it only print a file which has been through all the patterns without any setting "matchall" to 0.

1 Comment

Nifty. I added " > /dev/null" (without the quotes) to the grep command on line 4, just before the "||". This filtered out the noise and just gave me the results. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.