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
Recursive Search
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
Case Insensitive Search
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).
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
Print Lines Before a Match
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
Print Lines After a Match
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.