Grep Command in Linux (Find Text in Files)

Introduction

Before we discuss grep command in Linux (Find Text in Files) let's first understand-What is grep Command ?

The grep command, which stands for "global regular expression print," is one of Linux's most powerful and widely used commands.

grep looks for lines that match a pattern in one or more input files and outputs each matching line to standard output. grep reads from the standard input, which is usually the output of another command, if no files are specified.

In this tutorial, you will use grep command that looks for lines that match a pattern in one or more input files and outputs. We will also address a few FAQs on Grep Command in Linux (Find Text in Files).

grep Command Syntax

The grep command has the following syntax:

grep [OPTIONS] PATTERN [FILE...]

Optional items are those in square brackets.

  • File - Names of one or more input files.
  • PATTERN - Look for a pattern.
  • OPTIONS - A set of zero or more choices. grep has a lot of settings that govern how it behaves.

    The user performing the command must have read access to the file in order to search it.

In Files, Look for a String

The grep command's most basic use is to look for a string (text) in a file.

For example, to see all the entries in the /etc/passwd file that contains the string bash, use the following command:

grep bash /etc/passwd

This is what the output should look like:

root:x:0:0:root:/root:/bin/bash
vega:x:1000:1000:vega:/home/vega:/bin/bash

If the string contains spaces, use single or double quotation marks to surround it:

grep "Gnome Display Manager" /etc/passwd

Invert Match (Exclude)

Use the -v (or --invert-match) option to display lines that do not match a pattern.

To print the lines that do not contain the string nologin, for example, type:

grep -v nologin /etc/passwd
Output

root:x:0:0:root:/root:/bin/bash
colord:x:124:124::/var/lib/colord:/bin/false
git:x:994:994:git daemon user:/:/usr/bin/git-shell
vega:x:1000:1000:vega:/home/vega:/bin/bash

Use Grep to Filter the Output of a Command

The output of a command can be filtered using grep and pipe, with just the lines matching a specific pattern being printed on the terminal.

You can use the ps command to see which processes are running on your system as user www-data, for example:

ps -ef | grep www-data
Output

www-data 18247 12675  4 16:00 ?        00:00:00 php-fpm: pool www
root     18272 17714  0 16:00 pts/0    00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn www-data
www-data 31147 12770  0 Oct22 ?        00:05:51 nginx: worker process
www-data 31148 12770  0 Oct22 ?        00:00:00 nginx: cache manager process

You can also use a single command to bring in several pipes. There is also a line in the output above that contains the grep process, as you can see. Pass the output to another grep instance as described below if you don't want that line to be displayed.

ps -ef | grep www-data | grep -v grep
Output

www-data 18247 12675  4 16:00 ?        00:00:00 php-fpm: pool www
www-data 31147 12770  0 Oct22 ?        00:05:51 nginx: worker process
www-data 31148 12770  0 Oct22 ?        00:00:00 nginx: cache manager process

Invoke grep with the -r option to recursively search for a pattern (or --recursive). When this option is supplied, grep will scan all files in the specified directory, skipping any recursively encountered symlinks.

Instead of -r, use the -R option to follow all symbolic links (or --dereference-recursive).

Here's an example of how to search all files in the /etc directory for the string vegastack.com:

grep -r vegastack.com /etc

You will get an output like below:

Output

/etc/hosts:127.0.0.1 node2.vegastack.com
/etc/nginx/sites-available/vegastack.com:    server_name vegastack.com   www.vegastack.com;

grep will follow all symbolic links if you use the -R option:

grep -R vegastack.com /etc

Take note of the output's last line. Because files in Nginx's sites-enabled directory are symlinks to configuration files in the sites-available directory, that line is not shown when grep is run with -r.

Output

/etc/hosts:127.0.0.1 node2.vegastack.com
/etc/nginx/sites-available/vegastack.com:    server_name vegastack.com   www.vegastack.com;
/etc/nginx/sites-enabled/vegastack.com:    server_name vegastack.com   www.vegastack.com;

Show Only the Filename

Use the -l (or --files-with-matches) option to suppress the default grep output and only print the names of files containing the matched pattern.

The command below searches the current working directory for all files ending in .conf and prints just the names of the files that contain the string vegastack.com:

grep -l vegastack.com *.conf

You will get an output like below:

tmux.conf
haproxy.conf

Usually, the -l option is combined with the recursive option -R:

grep -Rl vegastack.com /tmp

grep is case-sensitive by default. The uppercase and lowercase characters are treated separately in this scenario.

When using grep, use the -i option to ignore case when searching (or --ignore-case).

When searching for Zebra without any options, for example, the following command will not return any results, despite the fact that there are matching lines:

grep Zebra /usr/share/words

However, if you use the -i option to perform a case-insensitive search, it will match both upper and lower case letters:

grep -i Zebra /usr/share/words

"Zebra" will match "zebra", "ZEbrA", or any other upper and lower case letter combination for that string.

zebra
zebra's
zebras

Search for Full Words

grep will display all lines where the string is embedded in larger strings while searching for a string.

If you search for "gnu," for example, you'll find all lines where "gnu" is embedded in larger terms like "cygnus" or "magnum":

grep gnu /usr/share/words
Output

cygnus
gnu
interregnum
lgnu9d
lignum
magnum
magnuson
sphagnum
wingnut

Use the -w (or --word-regexp) option to return only lines where the provided string is a whole word (contained by non-word characters).

💡
Alphanumeric characters (a-z, A-Z, and 0-9) and underscores (_) make up word characters. Non-word characters are all the rest of the characters.

If you execute the same program with the -w option, the grep command will only return lines that contain the word gnu as a distinct word.

grep -w gnu /usr/share/words
Output

gnu

Show Line Numbers

The -n (or --line-number) option instructs grep to display the line number of lines containing a pattern-matching string. grep prints the matches to standard output, prefixed with the line number, when this option is used.

You may use the following command to display the lines from the /etc/services file containing the string bash prefixed with the corresponding line number:

grep -n 10000 /etc/services

The matches are found on lines 10123 and 10124, as seen in the output below.

Output

10123:ndmp            10000/tcp
10124:ndmp            10000/udp

Count Matches

Use the -c (or --count) option to print a count of matching lines to standard output.

We're measuring the number of accounts that use /usr/bin/zsh as a shell in the example below.

regular expression
grep -c '/usr/bin/zsh' /etc/passwd
Output

4

Quiet Mode

The -q (or --quiet) option instructs grep to execute in silent mode, with no output to the standard output. The command leaves with status 0 if a match is found. This is handy when using grep in shell scripts to check if a file contains a string and then conduct a specific action based on the result.

Here's an example of using grep as a test command in an if statement in quiet mode:

if grep -q PATTERN filename
then
    echo pattern found
else
    echo pattern not found
fi

Basic Regular Expression

Basic, Extended, and Perl-compatible regular expression feature sets are available in GNU Grep.

grep interprets the pattern as a basic regular expression by default, with all characters except the meta-characters being regular expressions that match each other.

The following is a list of the most prevalent meta-characters:

  • To match a phrase at the beginning of a line, use the ^ (caret) symbol. The string kangaroo will only match in the following example if it appears at the very beginning of a line.
grep "^kangaroo" file.txt
  • To match an expression at the end of a line, use the $ (dollar) sign. In the example below, the string kangaroo will only match if it appears at the end of a line.
grep "kangaroo$" file.txt
  • To match a single character, use the . (period) sign. For example, you could use the following pattern to match anything that starts with kan, then has two characters, and ends with the string roo:
grep "kan..roo" file.txt
  • To match any single character wrapped in brackets, use [] (brackets). To discover the lines that contain the words "accept" or "accent," apply the following pattern:
grep "acce[np]t" file.txt
  • To match any single character that isn't enclosed in brackets, use []. The following pattern will match any combination of strings containing co(any letter except l) a, such as coca, cobalt, and so on, but not cola.
grep "co[^l]a" file.txt

Use the (backslash) symbol to get around the next character's specific meaning.

Extended Regular Expressions

Use the -E (or --extended-regexp) option to interpret the pattern as an extended regular expression. To generate more complicated and powerful search patterns, extended regular expressions include all of the fundamental meta-characters as well as additional meta-characters. Here are a few examples:

  • All email addresses in a given file are matched and extracted:
grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txt
  • From a given file, find and extract all valid IP addresses:
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' file.txt

Only the matching string is printed using the -o option.

Search for Multiple Strings (Patterns)

The OR operator | can be used to connect two or more search patterns.

grep reads the pattern as a normal regular expression by default, which means that meta-characters like | lose their special significance and should be replaced with their backslashed variants.

We're looking for all occurrences of the words fatal, error, and critical in the Nginx log error file in the example below:

grep 'fatal\|error\|critical' /var/log/nginx/error.log

The operator | should not be escaped if you use the extended regular expression option -E, as demonstrated below:

grep -E 'fatal|error|critical' /var/log/nginx/error.log

Use the -B (or --before-context) option to print a certain number of lines before matching lines.

For example, you could use the following command to display five lines of leading context before matching lines:

grep -B 5 root /etc/passwd

Use the -A (or --after-context) option to output a certain number of lines following matching lines.

For example, you could use the following command to display five lines of trailing context after matching lines:

grep -A 5 root /etc/passwd

FAQs on Grep Command in Linux

How does the grep command work in Linux?

grep searches for a specific pattern or regular expression in files or input streams, line-by-line. It outputs the lines that match the pattern to the console.

How do I use the grep command to search for a specific pattern in files?

To search for a pattern in files, use the grep command followed by the pattern and the file(s) to search. For example, grep 'pattern' file.txt.

Can grep search for patterns in multiple files simultaneously?

Yes, grep can search for patterns in multiple files at once. Simply specify the files you want to search after the pattern. For example, grep 'pattern' file1.txt file2.txt.

How can I search for a pattern in all files within a directory and its subdirectories?

You can use the -r or --recursive flag with grep to search for patterns recursively within a directory and its subdirectories. For example, grep -r 'pattern' directory/.

What is the difference between grep and grep -i?

The grep -i command performs a case-insensitive search, meaning it matches patterns regardless of letter case. grep without the -i flag performs a case-sensitive search.

Can I use regular expressions with the grep command?

Yes, grep supports regular expressions. By default, it uses basic regular expressions, but you can enable extended regular expressions using the -E or --extended-regexp flag.

Can grep search for patterns based on whole words only?

Yes, you can use the -w or --word-regexp option with grep to match patterns based on whole words only. For example, grep -w 'word' file.txt will only match lines containing the exact word "word".

Conclusion

You can use the grep command to look for a pattern within files. If grep finds a match, it outputs the lines that contain the provided pattern.

The Grep User's Manual page has a lot more information on grep.

If you have any queries, please leave a comment below and we’ll be happy to respond to them.