String Pattern Using grep Command on Bash shell

How do I grep for multiple patterns?

The syntax is:

Use single quotes in the pattern: grep 'pattern*' file1 file2
Next use extended regular expressions: egrep 'pattern1|pattern2' *.py
Finally, try on older Unix shells/oses: grep -e pattern1 -e pattern2 *.pl

Grep searching two words in a line

Here are all other possibilities for grep and egrep command:

grep 'word1\|word2\|word3' /path/to/file

### Search all text files ###
grep 'word*' *.txt

### Search all python files for 'wordA' or 'wordB' ###
grep 'wordA*'\''wordB' *.py
grep -E 'word1|word2' *.doc
grep -e string1 -e string2 *.pl
egrep "word1|word2" *.c

### Show all the lines that do not match given pattern/words/strings ###
grep -v 'bar\|foo' /dir1/dir2/file1
egrep -v 'pattern1|pattern2' /path/to/file

Examples

In this example, search warning, error, and critical words in a text log file called /var/log/messages, enter:

$ grep 'warning\|error\|critical' /var/log/messages

To just match words, add the -w option:

$ grep -w 'warning\|error\|critical' /var/log/messages

Use the egrep command and you can skip the above syntax to search three words:

$ egrep -w 'warning|error|critical' /var/log/messages

Grep multiple patterns

Sometimes we need to grep multiple patterns with special character such as ‘-‘ or ‘--‘. For example, search for pattern starting with ‘--ca‘ or ‘--no‘ words. So if you try the following you will get an error on screen such as “grep: unrecognized option : --ca|--no“. Let us try an example:

$ acme.sh --help | egrep '--ca|--no'

In order to tell grep not to treat ‘--‘ as command line option prefix pattern as follows:

$ acme.sh --help | egrep -- '--ca|--no'
$ virt-sysprep --help | egrep -- '--(truncate|run)'

All other grep or egrep command option must appear before the final --. For instance pass the -w and --color as follows:

acme.sh --help | egrep --color -w -- '--ca|--no'

How to find multiple strings in files?

Let us try a few more examples with additional options passed to the grep/egrep:

$ grep -e 'warning\|error\|critical' /var/log/messages

I recommend that you pass the -i (ignore case) and --color option as follows too:

$ egrep -wi --color 'warning|error|critical' /var/log/messages

When using grep command, pipe (|) meta-character must be escaped with a backslash, and there are no such requirements for egrep.
To search all *.conf files under /etc/, enter:

# egrep -wi --color 'foo|bar' /etc/*.conf

To search recursively (including sub-directories) listed, run:

# egrep -Rwi --color 'foo|bar' /etc/

Where options are as follows:

-R : Recursive search
-w : Match only words
-i : Ignore case distinctions. In other words match FOO, foo, Foo and so on.
--color : Surround the matched in color on the terminal. For example, display matched strings in colors.
-v : Invert the sense of matching, to select non-matching line. In other words, search and display all the lines, that do not match our strings or words

grep multiple strings using awk

Say if you are already using the awk command or sed command command, then there is no need to pipe out to grep and feed data from grep. We can process and gather multiple strings using awk or sed as follows to save CPU cycle:

awk command syntax

$ awk '/error|critical/failed/' /var/log/httpd/error_log

## case instive search with *gnu/awk* ##
$ awk 'BEGIN{IGNORECASE=1} /error|critical/failed/' /var/log/messages
$ awk '/word1.*word2/' input
$ awk '/myPattern1/ && /myPattern2/' /path/to/file

## awk not matching i.e. show all line except HTTP/2.0 logs ##
$ awk '!/HTTP\/2.0/' /var/log/nginx/cyberciti.bizerror_log

sed command syntax

$ sed -e '/error/b' -e '/critcial/b' -e d /var/log/apache/nixcraft.com_error_log
$ sed '/stringOne/!d; /stringTwo/!d' ~/backups/conf.txt

## sed negative (NOT) matching. For example, show all hosts except cbz01-www ##
$ sed -n '/cbz01-www/!p' /etc/hosts