grep
is a Linux command that finds and displays a text string in one or more files. It scans each line of the file for the string and outputs the matching lines. It is a useful tool for searching and processing text data fast and effectively. You can use the command to look for specific words, phrases, or patterns in files of any size, from small text files to large log files. If you don’t specify any files, grep
takes the standard input, which is usually the output of another command, as the source.
In this article, you will learn how to apply the grep command in various scenarios with detailed descriptions of the most frequently used GNU grep options.
grep
Command Syntax
The grep command has this syntax:
grep [OPTIONS] PATTERN [FILE...]
The parts in square brackets can be omitted.
OPTIONS
- Any number of options. Grep has many options that modify how it works.
PATTERN
- The text or pattern to look for.
FILE
- The name(s) of the file(s) to search in.
The user who runs the command needs read permission on the file to search it.
How To Search For Strings in Files
The grep
command allows you to search for a text string in a file.
For example, to search for the word “bash” in the /etc/passwd
file, you can use this command:
grep bash /etc/passwd
This will display the lines that have the word “bash” in them, such as:
root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
Copy The word “bash” is the name of the shell program that the users use to interact with the system. The /etc/passwd
file contains information about the users on the system.
If you want to search for a phrase that has spaces, you have to put it in quotes:
grep "Gnome Display Manager" /etc/passwd
This will search for the exact phrase “Gnome Display Manager” in the file. Gnome Display Manager is a graphical login program for Linux systems.
Inverse Match (Exclude)
The -v
(or --invert-match
) option lets you show the lines that are not matching a pattern.
For instance, to show the lines that do not have the word “nologin” in them, you can use this command:
grep -v nologin /etc/passwd
This will display the lines that have a different word after the last colon, such as:
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
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
The word “nologin” indicates that the user cannot log in to the system. The /etc/passwd
file contains information about the users on the system.
Filtering Command Output with Grep
You can use grep to filter the output of a command by piping it, and only the lines that match a given pattern will be shown on the terminal. This can help you find specific information in a large output more easily.
For example, to see which processes are running on your system as user www-data you can use this ps command:
ps -ef | grep www-data
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 multiple pipes in one command. As you can see in the output above, there is a line with the grep process. If you want to remove that line from the output, you can use another grep instance, as shown below:
ps -ef | grep www-data | grep -v grep
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
Searching Recursively
To search for a pattern recursively, use grep
with the -r
option (or --recursive
). This option will make grep search through all files in the given directory, including its subdirectories, and skip the symlinks that are found recursively. This lets you search through your whole directory structure to find what you need.
To follow all symbolic links instead of -r,
use the -R
option (or --dereference-recursive
).
Here is an example of how to search for the string freecodecamp.org in all files in the /etc directory:
grep -r freecodecamp.org /etc
The output will have matching lines with the full path to the file:
/etc/hosts:127.0.0.1 node2.freecodecamp.org
/etc/nginx/sites-available/freecodecamp.org: server_name freecodecamp.org www.freecodecamp.org;
If you use the -R option, grep will follow all symbolic links:
grep -R freecodecamp.org /etc
Notice the last line of the output below. That line is not shown when grep is used with -r
because files in the Nginx’s sites-enabled
directory are symlinks to configuration files in the sites-available
directory.
Output:
/etc/hosts:127.0.0.1 node2.freecodecamp.org
/etc/nginx/sites-available/freecodecamp.org: server_name freecodecamp.org www.freecodecamp.org;
/etc/nginx/sites-enabled/freecodecamp.org: server_name linuxize.com www.freecodecamp.org;
Showing Only the Filename
To hide the default grep
output and show only the names of files that have the matched pattern, use the -l
( or --files-with-matches
) option.
The following command will search for all files that end with .conf
in the current working directory and show only the names of the files that have the string freecodecamp.org:
grep -l freecodecamp.org *.conf
The output will be something like this:
tmux.conf
haproxy.conf
The -l
option is often used with the recursive option -R
:
grep -Rl freecodecamp.org /tmp Copy
Search without Case Sensitivity
By default, grep
distinguishes between uppercase and lowercase letters. For example, searching for “linux” will not find “Linux”.
To search without case sensitivity, use grep
with the -i
option (or --ignore-case
).
For example, if you search for Zebra
without any option, the following command will not find any matches:
grep Zebra /usr/share/words
But if you search without case sensitivity using the -i option, it will find both upper and lower case letters:
grep -i Zebra /usr/share/words
In the command above “Zebra” will find “zebra”, “ZEbRA” or any other mix of upper and lower case letters for that word.
zebra
zebras
zebra’s
Search for Whole Words
When searching for a word, grep
will show all lines where the word is part of a larger word or a separate word.
For example, if you search for the word “gnu”, grep will show all the lines that have “gnu” as a standalone word or as part of a larger word such as “cygnus” or “magnum”.
grep gnu /usr/share/words
Sample Output:
cygnus
gnu
interregnum
lgnu9d
lignum
magnum
magnuson
sphagnum
wingnut
To show only those lines where the word is a whole word (surrounded by non-word characters), use the -w
( or --word-regexp
) option.
Word characters are letters (a-z, A-Z), numbers (0-9) and underscores (_). All other characters are non-word characters.
If you use the command with the -w
option, the grep
command will show only those lines where gnu is a separate word.
grep -w gnu /usr/share/words
Output:
gnu
Show Line Numbers
The -n
( or --line-number
) option makes grep show the line number of all the lines that match a pattern. When this option is used, grep
shows the matched lines with their line numbers before them.
For example, to show the lines from the /etc/services
file that have the word bash with their line numbers, you can use this command:
grep -n 10000 /etc/services
The output below tells us that the matches are on lines 10423 and 10424.
10423:ndmp 10000/tcp
10424:ndmp 10000/udp