ewok
ewok

Reputation: 21453

grep regex: search for any of a set of words

I want to search a large set of files for a set of words in any order, with or without spaces or punctuation. so, for example, if I search hello, there, friend, it should match

hello there my friend
friend, hello there
theretherefriendhello

but not

hello friend
there there friend

I can't figure out any way to do this. is it even possible to do using grep, or some variation of grep?

Upvotes: 2

Views: 77

Answers (4)

hek2mgl
hek2mgl

Reputation: 158010

You can use sed:

sed -n '/word1/{/word2/{/word3/p;};}' *.txt

Upvotes: 2

ghoti
ghoti

Reputation: 46856

In an Basic and Extended RE, without using vendor- or version-specific extensions like Perl RE, you would need to handle this using something like this:

egrep  -lr 'hello.*there.*friend|hello.*friend.*there|there.*hello.*friend|there.*friend.*hello|friend.*hello.*there|friend.*there.*hello' /path/

Note the -l option to tell you only filenames, and -r to tell grep to search recursively. This solution should work on pretty much every variation of grep that you might come across.

This is obviously inelegant in terms of the RE, but handy in terms of using grep's built-in recursive search. If the RE bothers you, I would use awk or sed for this instead, if you can, wrapped in find:

find /path/ -exec awk '/hello/&&/there/&&/friend/ {r=1} END {exit 1-r}'\; -print

Again, the output of this is a list of files, rather than a list of lines. You can adjust to suit your specific requirements.

Upvotes: 2

fedorqui
fedorqui

Reputation: 289745

For this purpose I wouldl use awk like this:

awk '/hello/ && /there/ && /friend/' file

This checks if the current line contains all the strings: hello, there and friend. If this happens, the line is printed

Why? because then the condition is True and the default behaviour of awk when something is True is to print the current line.

Upvotes: 2

vks
vks

Reputation: 67968

is it even possible to do using grep, or some variation of grep?

You can use grep -P ie in Perl mode,the following regex.

^(?=.*hello)(?=.*there)(?=.*friend).*$

See demo.

https://regex101.com/r/sJ9gM7/37

Upvotes: 2

Related Questions