Grep Command in Linux with Examples

Grep is one of the most commonly used commands in Linux. The name stands for “Global Regular Expression Print”.
The grep command searches for a text pattern in one or more files and prints every line that matches. It is a powerful tool for searching and analyzing large amounts of text data quickly and efficiently. You can use it to search for specific words, phrases, or regular expressions
in files of any size, from small configuration files to large log files. If no files are specified, grep reads from standard input, which is usually the output of another command.
This guide covers the most common GNU grep options with practical examples.
grep Command Syntax
The syntax for the grep command is as follows:
grep [OPTIONS] PATTERN [FILE...]The items in square brackets are optional.
OPTIONS- Zero or more options. Grep includes a number of options that control its behavior.PATTERN- The search pattern (string or regular expression).FILE- Zero or more input file names.
To search a file, the user running the command must have read access to it.
Search for a String in Files
The most basic usage of the grep command is to search for a string (text) in a file.
For instance, to find all lines containing the string “bash” in the /etc/passwd
file, run the following command:
grep bash /etc/passwdThe output shows every line that contains the matching string:
root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bashIf the string contains spaces, enclose it in single or double quotation marks:
grep "Gnome Display Manager" /etc/passwdCase Insensitive Search
By default, grep is case-sensitive, meaning uppercase and lowercase characters are treated as distinct.
To ignore case when searching, use the -i option (or --ignore-case).
For example, searching for “Zebra” without -i will not match lowercase entries:
grep Zebra /usr/share/dict/wordsNo output is produced because there are no lines matching the exact case. If you perform a case-insensitive search using the -i option, it will match all variations:
grep -i Zebra /usr/share/dict/wordszebra
zebra's
zebrasSearch for Full Words
When searching for a string, grep displays all lines where the string appears, even if it is embedded in a larger word.
For example, if you search for “gnu”, grep will match lines containing “gnu” as well as words like “cygnus” or “magnum”:
grep gnu /usr/share/dict/wordscygnus
gnu
interregnum
lignum
magnum
magnuson
sphagnum
wingnutTo return only lines where the specified string is a whole word (enclosed by non-word characters), use the -w option (or --word-regexp):
grep -w gnu /usr/share/dict/wordsgnua-z, A-Z, and 0-9) and underscores (_). All other characters are considered non-word characters.Invert Match (Exclude)
Use the -v option (or --invert-match) to display lines that do not match a pattern.
For example, to print lines that do not contain the string “nologin”:
grep -v nologin /etc/passwdroot: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/bashRecursive Search
To recursively search for a pattern, invoke grep with the -r option (or --recursive). When this option is used, grep searches through all files in the specified directory and its subdirectories, skipping symlinks that are encountered recursively.
To follow all symbolic links
, use the -R option (or --dereference-recursive) instead.
Here is an example showing how to search for the string linuxize.com in all files inside the /etc directory:
grep -r linuxize.com /etcThe output includes matching lines prefixed by the full path to the file:
/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com;If you use the -R option, grep will follow all symbolic links:
grep -R linuxize.com /etcNotice the last line in the output below. It is not printed when grep is invoked with -r because files inside Nginx’s sites-enabled directory are symlinks to configuration files inside sites-available:
/etc/hosts:127.0.0.1 node2.linuxize.com
/etc/nginx/sites-available/linuxize.com: server_name linuxize.com www.linuxize.com;
/etc/nginx/sites-enabled/linuxize.com: server_name linuxize.com www.linuxize.com;For faster recursive searches in code repositories, ripgrep
is often a better default because it respects ignore files and searches recursively without extra flags.
Show Only the Filename
To suppress the default grep output and print only the names of files containing a match, use the -l option (or --files-with-matches).
The following command searches for all files ending with .conf in the current working directory
and displays only the file names:
grep -l linuxize.com *.conftmux.conf
haproxy.confThe -l option is commonly used together with the recursive option -R:
grep -Rl linuxize.com /tmpShow Line Numbers
The -n option (or --line-number) tells grep to prefix each matching line with its line number in the file.
For instance, to display matching lines from /etc/services containing the string 10000 with their line numbers:
grep -n 10000 /etc/servicesThe output shows that the matches are found on lines 10423 and 10424:
10423:ndmp 10000/tcp
10424:ndmp 10000/udpCount Matches
To print only the number of matching lines instead of the lines themselves, use the -c option (or --count).
In the following example, we count the number of accounts that have /usr/bin/zsh as their shell:
grep -c '/usr/bin/zsh' /etc/passwd4Print Only the Matching Part
The -o option (or --only-matching) tells grep to print only the matched portion of each line, rather than the entire line. This is especially useful when extracting specific patterns with regular expressions.
For example, to extract all words starting with “log” from a file:
grep -o 'log[a-z]*' /var/log/syslog | head -5Context Lines
By default, grep prints only the lines that match. You can use context options to also display lines surrounding each match.
To print a specific number of lines before each match, use the -B option (or --before-context):
grep -B 3 "error" /var/log/syslogTo print a specific number of lines after each match, use the -A option (or --after-context):
grep -A 3 "error" /var/log/syslogTo print lines both before and after each match, use the -C option (or --context):
grep -C 3 "error" /var/log/syslogWhen multiple matches are close together, grep separates groups of context lines with --.
Using Grep to Filter Command Output
A command’s output can be filtered with grep through piping, and only lines matching a given pattern will be printed. This is one of the most common uses of grep.
For instance, to find which processes are running as user www-data, you can pipe the output of the ps
command to grep:
ps -ef | grep www-datawww-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 processNote that grep may also match its own process in the output. A common trick to avoid this is to use a character class in the pattern:
ps -ef | grep '[w]ww-data'By wrapping the first character in brackets, the grep command itself no longer matches the pattern.
Search for Multiple Strings (Patterns)
Two or more search patterns can be joined using the OR operator |.
By default, grep interprets the pattern as a basic regular expression, where | must be escaped with a backslash:
grep 'fatal\|error\|critical' /var/log/nginx/error.logIf you use the extended regular expression option -E, the operator does not need to be escaped:
grep -E 'fatal|error|critical' /var/log/nginx/error.logFor more complex multi-pattern searches, see Grep Multiple Patterns .
Basic Regular Expressions
GNU Grep has three regular expression feature sets: Basic, Extended, and Perl-compatible.
By default, grep interprets the pattern as a basic regular expression (BRE), where all characters except the meta-characters match themselves.
Below is a list of the most commonly used meta-characters:
^- Matches the start of a line. In the following example,kangaroomatches only if it occurs at the beginning of a line:Terminalgrep "^kangaroo" file.txt$- Matches the end of a line. Here,kangaroomatches only if it occurs at the end of a line:Terminalgrep "kangaroo$" file.txt.- Matches any single character. To match anything that begins withkan, then has two characters, and ends withroo:Terminalgrep "kan..roo" file.txt[ ]- Matches any single character enclosed in the brackets. For instance, to find lines that containacceptoraccent:Terminalgrep "acce[np]t" file.txt[^ ]- Matches any single character not enclosed in the brackets. The following pattern matches strings likecocaorcoma, but notcola:Terminalgrep "co[^l]a" file.txt
To escape the special meaning of a meta-character, use the \ (backslash) symbol.
Extended Regular Expressions
To interpret the pattern as an extended regular expression (ERE), use the -E option (or --extended-regexp). Extended regular expressions include all basic meta-characters plus additional ones such as +, ?, |, and ().
Here is an example that matches and extracts all email addresses from a file:
grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" file.txtThe following example matches and extracts all valid IPv4 addresses from a file:
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.txtThe -o option prints only the matched portion of each line, not the entire line.
Excluding Files and Directories
When searching recursively, you can exclude specific files or directories using --exclude and --exclude-dir.
To exclude all .log files from a recursive search:
grep -r --exclude="*.log" "pattern" /path/to/directoryTo exclude multiple file types, repeat the --exclude option:
grep -r --exclude="*.log" --exclude="*.tmp" "pattern" /path/to/directoryTo exclude a directory from the search:
grep -r --exclude-dir="node_modules" "pattern" /path/to/directoryFor more details and examples, see Grep Exclude .
Quiet Mode
The -q option (or --quiet) tells grep to run silently without displaying anything on standard output. If a match is found, the command exits with status 0. This is useful in shell scripts where you want to check whether a file contains a string and perform an action based on the result.
Here is an example of using grep in quiet mode as a test command in an if statement
:
if grep -q PATTERN filename
then
echo pattern found
else
echo pattern not found
fiUsing Shell Variables with Grep
When using grep in shell scripts, you can pass shell variables as the search pattern. Enclose the variable in double quotes to prevent word splitting and globbing:
pattern="search term"
grep "$pattern" file.txtTo use a variable as a fixed string (disabling regex interpretation), combine it with the -F option:
grep -F "$pattern" file.txtLimit the Number of Matches
The -m option (or --max-count) tells grep to stop reading a file after a specified number of matching lines. This is useful when working with large files and you only need the first few matches.
For example, to print only the first five lines containing “error” in a log file:
grep -m 5 "error" /var/log/syslogGrep stops reading the file as soon as it finds five matches, which can save a lot of time on large files.
Suppress Error Messages
By default, grep prints error messages when it cannot read a file or when a file does not exist. The -s option (or --no-messages) silences these messages.
This is helpful in shell scripts where you want to ignore “No such file or directory” or “Permission denied” warnings:
grep -s "pattern" /etc/*.confAny files that cannot be read are skipped silently, and only the actual matches are printed.
Hide Filenames in Output
When grep searches multiple files, it prefixes each matching line with the file name. The -h option (or --no-filename) suppresses these prefixes and prints only the matching lines.
For example, to search for “PermitRootLogin” across all SSH configuration files without showing file names:
grep -h "PermitRootLogin" /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.confThis is useful when piping the output to another command or when the file names would only add noise to the result.
Search Binary Files as Text
Grep treats binary files differently from text files and prints a message like Binary file FILE matches instead of the actual content. The -a option (or --text) forces grep to process binary files as if they were text.
To search for a string in a binary file or a data file that contains non-text bytes:
grep -a "version" archive.datThe matching lines are printed even though the file may contain non-printable characters. Be aware that the output may include control characters that affect your terminal.
Combining Grep with find
When you need more control over which files are searched, combine grep with the find command using -exec. This is helpful when you want to filter by file attributes such as modification time, size, or permissions before searching their contents.
For example, to search for “TODO” in all .py files modified in the last seven days:
find . -type f -name "*.py" -mtime -7 -exec grep -l "TODO" {} +The find command locates the matching files, and grep -l prints the names of files that contain the pattern. Using + instead of \; passes files to grep in batches, which is much faster than invoking grep once for each file.
Quick Reference
For a printable quick reference, see the Grep cheatsheet .
| Task | Command |
|---|---|
| Search for a string | grep "pattern" file |
| Case insensitive search | grep -i "pattern" file |
| Whole word match | grep -w "word" file |
| Invert match | grep -v "pattern" file |
| Recursive search | grep -r "pattern" /path |
| Show filenames only | grep -rl "pattern" /path |
| Show line numbers | grep -n "pattern" file |
| Count matches | grep -c "pattern" file |
| Print only matching part | grep -o "pattern" file |
| Lines before match | grep -B 3 "pattern" file |
| Lines after match | grep -A 3 "pattern" file |
| Lines around match | grep -C 3 "pattern" file |
| Multiple patterns | grep -e "pat1" -e "pat2" file |
| Fixed string (no regex) | grep -F "literal.string" file |
| Exclude files | grep -r --exclude="*.log" "pattern" /path |
| Exclude directories | grep -r --exclude-dir=".git" "pattern" /path |
| Recursive with line numbers | grep -rn "pattern" /path |
| Hide filenames | grep -h "pattern" file1 file2 |
| Limit matches | grep -m 5 "pattern" file |
| Suppress errors | grep -s "pattern" file |
| Search binary as text | grep -a "pattern" binary |
| Find and grep | find . -name "*.py" -exec grep -l "pattern" {} + |
FAQ
What does grep do?
The grep command searches text for lines that match a pattern. It reads input from files or standard input, applies a search pattern (either a literal string or a regular expression), and prints every matching line. It is one of the most-used tools for filtering log files, extracting data from command output, and finding code in projects.
What does grep mean?
The name stands for “Global Regular Expression Print”. It comes from the ed text editor command g/re/p, which globally searches for a regular expression and prints matching lines. Grep became a standalone Unix utility in 1973 and has shipped with every major Unix-like system since.
What is the difference between grep and egrep?
The egrep command is equivalent to grep -E. It interprets the pattern as an extended regular expression, which means meta-characters like +, ?, |, and () do not need to be escaped. The egrep command is deprecated in favor of grep -E.
How do I search for a string in all files in a directory?
Use the -r (recursive) option: grep -r "pattern" /path/to/directory. This searches all files in the directory and its subdirectories. Add --include="*.txt" to limit the search to specific file types.
How do I search for multiple words with grep?
Use the -E option with the alternation operator: grep -E "word1|word2|word3" file. Without -E, escape the pipe characters: grep "word1\|word2\|word3" file.
What is the difference between grep, sed, and awk?
Grep is designed for searching and filtering lines that match a pattern. Sed is a stream editor for transforming text with find-and-replace operations. Awk is a full programming language for field-based text processing and data extraction. Use grep to find lines, sed to modify text, and awk to process columnar data.
Conclusion
The grep command is an essential tool for searching text patterns in files and command output. Combined with regular expressions and options like -r, -i, and -E, it handles everything from simple string searches to complex pattern matching.
For more information, see the official Grep manual .
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page