Smeterlink
Smeterlink

Reputation: 796

Search for several patterns at the same time in a list of text files

I have a folder with text files, and want to search inside all the text files, if they have certain words at the same time, not necessarily in the same line. I've tried with grep but works line by line:

file-1.txt:

You shall find of the king a husband, madam; you,
sir, a father: he that so generally is at all times
good must of necessity hold his virtue to you; whose
worthiness would stir it up where it wanted rather
than lack it where there is such abundance.

file-2.txt:

He was excellent necessity, madam: the father very
lately spoke of him admiringly and mourningly: he
was skilful enough to have lived still, if knowledge
could be set up against mortality.
He hath abandoned his physicians, king; under whose
practises he hath persecuted time with hope, and
finds no other advantage in the process but only the
losing of hope by time.

I want to detect if king and father are present in the same file. The code I've tried is:

for file in file-*.txt; do grep -E 'king.*father' "$file" && echo $file; done

But no luck. Any help?

Upvotes: 0

Views: 41

Answers (2)

Smeterlink
Smeterlink

Reputation: 796

Answering my own question, @Technologeeks answer is on point:

for file in file-*.txt; do egrep -z  '(king.*father|father.*king)' "$file" && echo $file; done

However, to search for lots of words at the same time:

for file in file-*.txt; do grep -q 'king' "$file" && grep -q 'father' "$file" && grep -q 'freedom' "$file" && grep -q 'matter' "$file" && echo $file; done

Can be done also with -z on each grep. Also add -q on last one:

for file in file-*.txt; do cat "$file" | grep -z father | grep -z king | grep -z -q time && echo "$file" ; done

Upvotes: 0

Technologeeks
Technologeeks

Reputation: 7907

You have two problems here:

A) grep -E still won't work across lines. Using -z will help, making all the file count as one line:

for file in file-*.txt; do grep -z  'king.*father' "$file" && echo $file; done
  • This will match file-1.txt

B) Do I understand you'll need the words in different order too? For that you'll need egrep, and specifying both expressions inside a (), separated by a |:

for file in file-*.txt; do egrep -z  '(king.*father|father.*king)' "$file" && echo $file; done

Upvotes: 1

Related Questions