2

How can we use grep to get line(s) containing a group of words, while the order of words is not important, although line(s) should contain all words mentioned in search?

I have done that with phasing the search (with piping, saving the outputs in temporary files, and searching again), but I'd like to know if I can do that in one attempt.

Here is a sample; I want to search in the lines below for lines containing sample, words, list:

it's a sample test file for a list of words.
list of words without a specific order, it's a sample.
line with no search keyword here.
list the sample files.
something completely different.

And get this result:

it's a sample test file for a list of words.
list of words without a specific order, it's a sample.
Peter Mortensen
  • 933
  • 2
  • 11
  • 17
arash deilami
  • 157
  • 2
  • 8

2 Answers2

4

The easy way is with multiple calls to grep:

grep sample testfile.txt | grep words | grep list

A demonstration:

echo -e "it's a sample test file for a list of words.\nlist of words without a specific order, it's a sample. \nline with no search keyword here. \nlist the sample words. \nsomething completely different." | grep sample | grep words | grep list
it's a sample test file for a list of words.
list of words without a specific order, it's a sample. 
list the sample words. 
waltinator
  • 35,099
  • 19
  • 57
  • 93
  • yes, this works as I've mentioned, but i'm looking for a one-line-solution. Although sometimes it's better to do things the easy way. thanks :) – arash deilami Aug 23 '18 at 18:11
  • grep -e also selects lines which have only two words (not all the words). Maybe I should try awk instead of grep, it works fine. Thank you all – arash deilami Aug 23 '18 at 18:18
4

You can use lookaheads with Perl-regex (-P):

grep -P '(?=.*list)(?=.*words)(?=.*sample)'

Example:

echo "it's a sample test file for a list of words.
list of words without a specific order, it's a sample.
line with no search keyword here.
list the sample words.
sample line with only two of the keywords inside.
something completely different." \
| grep -P '(?=.*list)(?=.*words)(?=.*sample)'

it's a sample test file for a list of words.
list of words without a specific order, it's a sample.
list the sample words.

(via)


With agrep (sudo apt install agrep) you can chain multiple patterns:

agrep "sample;words;list"

(via)

pLumo
  • 26,204
  • 2
  • 57
  • 87