In linux grep -r <string> <path>
is a common way to find all instances of in files under <path>
, which basically gives you all the files under <path>
which include <string>
. But what if I want to find all files which include few strings? From grep -r <string1> <path> | grep <string2>
I can get all files which include <string1>
and <string2>
in the same line, but how can I get the files which include <string1>
and <string2>
in separate lines?
Asked
Active
Viewed 773 times
4

e271p314
- 3,841
- 7
- 36
- 61
-
http://stackoverflow.com/questions/16956810/finding-all-files-containing-a-text-string-in-linux/20950539#20950539 – Dilawar Jan 06 '14 at 12:58
1 Answers
5
You can try
grep -rl searchstring1 . | xargs grep -l searchstring2
to get a list of file names in directory .
containing both searchstring
s (not necessarily in the same line). You can cascade that in case you want more search strings:
grep -rl searchstring1 . \
| xargs grep -l searchstring2 \
| xargs grep -l searchstring3
This is tricky in case you have spaces and other nasty characters in the file names because then the xargs
gets fooled. In such special cases (or just to be sure not to get that problem) you can use 0-byte terminated strings:
grep -rlZ searchstring1 . \
| xargs -0 grep -lZ searchstring2 \
| xargs -0 grep -l searchstring3
And to check the output you can use sth like:
grep -rlZ searchstring1 . \
| xargs -0 grep -lZ searchstring2 \
| xargs -0 grep -lZ searchstring3 \
| xargs -0 egrep 'searchstring2|searchstring2|searchstring3' /dev/null \
| less
A completely different approach is using find
straight forward (but that starts lots of grep
processes and is therefore probably less efficient):
find . -type f \( \
-exec grep -q searchstring1 {} \; -a \
-exec grep -q searchstring2 {} \; -a \
-exec grep -q searchstring2 {} \; \) -print

Alfe
- 56,346
- 20
- 107
- 159
-
`xargs` is a good option, this will work certainly and I will accept your answer, but are there alternatives? What I'm saying is that looking for files with few strings is a very basic problem and I would expect it could be solved without pipes. This is a scalability issue, ideally, I'm looking for a similar syntax to `
`. For simplicity we can assume that all strings are normal alpha numeric characters -
I added a `find` version in case you prefer that. Other options I could think of would involve using Python or similar. I can't think of a third way using just Unix standard tools. – Alfe Nov 05 '13 at 08:39
-
All in all I think your answer is sufficient, however, I'll be glad to hear answers which don't include pipes – e271p314 Nov 05 '13 at 08:50
-
-
As I said, first scalability, and the second is that it seems to me that it only makes sense to have a command or a flag which will handle this specific case. Even your first approach is almost as scalable as a pipe free solution but for readability and ease of use I prefer a single designated command – e271p314 Nov 05 '13 at 09:21
-
1Be aware that on multicore processors nowadays it often has advantages to split tasks into several separate processes. But I see your point. – Alfe Nov 05 '13 at 09:27