SSH & Terminal Access

Comprehensive Guide to `grep` Command: Advanced Usage and All Functions with Examples

By the Domain India teamPublished 6 min read
Knowledge base article
Contents (10 sections)

grep searches text for lines that match a pattern. It is the quickest way to find an error in a log, a setting in a config file, or a function in thousands of source files. This guide covers the options you will actually use, regular expressions, and practical examples for logs, code and security checks.

Key takeaways

grep 'text' file prints matching lines. Add -i to ignore case, -r to search a folder, -n for line numbers, -v to exclude matches, -c to count, -l to list file names, -w for whole words and -F for plain text with no regex. Use -E for extended regular expressions (egrep and fgrep are obsolete), -A, -B and -C for context lines, and zgrep for .gz logs. Quote your pattern in single quotes.

1. Basic syntax

bash
grep [OPTIONS] PATTERN [FILE...]
bash
grep 'error' app.log                 # lines containing "error"
grep 'error' app.log old.log         # several files; each line is prefixed with its file name
dmesg | grep -i usb                  # search the output of another command

Use single quotes around the pattern so the shell does not expand $, * or ! before grep sees them. grep is case-sensitive unless you add -i.

grep also reports through its exit status, which is useful in scripts: 0 means a match was found, 1 means none, 2 means an error such as a missing file.

bash
if grep -q 'maintenance_mode=1' config.ini; then
    echo 'Site is in maintenance mode'
fi

2. The options you will use most

OptionWhat it doesExample
-iIgnore upper and lower casegrep -i 'warning' app.log
-vShow lines that do NOT matchgrep -v '^#' config.conf
-nShow line numbersgrep -n 'DB_HOST' .env
-cCount matching linesgrep -c 'POST' access.log
-l / -LList files that do / do not matchgrep -rl 'wp_mail' wp-content/
-wMatch whole words onlygrep -w 'id' schema.sql
-xMatch whole lines onlygrep -x 'enabled' flags.txt
-oPrint only the matching partgrep -o 'user=[a-z]*' app.log
-m NStop after N matchesgrep -m 5 'error' big.log
-FTreat the pattern as plain textgrep -F '$price[0]' *.php
-eGive several patternsgrep -e 'error' -e 'fatal' app.log
-f FILERead patterns from a file, one per linegrep -f bad-ips.txt access.log
-h / -HHide / show file namesgrep -h 'error' *.log
-sHide "no such file" and permission errorsgrep -rs 'secret' /etc

Options can be combined: grep -rniw 'todo' src/ searches a folder recursively, ignoring case, for the whole word "todo", with line numbers.

3. Context lines

A single log line rarely tells the whole story. Show what came before and after it:

bash
grep -A 3 'Exception' app.log     # 3 lines After each match
grep -B 2 'Exception' app.log     # 2 lines Before
grep -C 5 'Exception' app.log     # 5 lines of Context on both sides

Groups of lines are separated by --.

4. Regular expressions

By default grep uses basic regular expressions (BRE). With -E you get extended syntax (ERE), where +, ?, |, {} and () work without backslashes. egrep and fgrep are old names for grep -E and grep -F; current GNU grep prints a warning when you use them.

PatternMatches
^errorLines starting with "error"
error$Lines ending with "error"
.Any single character
[0-9]One digit
[^a-z]Any character that is not a lower-case letter
colou?r (with -E)"color" or "colour"
[0-9]{3} (with -E)Exactly three digits
\bword\b"word" as a whole word (GNU grep)

With -E, a vertical bar means "or": grep -E 'cat|dog' matches either word.

bash
grep -E '^(GET|POST) ' requests.txt
grep -Eo '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}' contacts.txt   # pull out email addresses
grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' access.log | sort -u               # unique IPv4 addresses

GNU grep also has -P for Perl-compatible expressions, which adds lookarounds and \d:

bash
grep -oP '(?<=order_id=)\d+' app.log      # the number after "order_id="

To search for text containing regex characters, such as a.b or $var[0], use -F so nothing is treated as a pattern.

5. Searching folders

bash
grep -rn 'DB_PASSWORD' ~/public_html/                         # every file under the folder
grep -rn --include='*.php' 'mysql_query' ~/public_html/        # only PHP files
grep -rn --exclude-dir={node_modules,vendor,.git} 'TODO' .      # skip heavy folders
grep -rl 'old-domain.com' ~/public_html/                       # just the file names

-r follows symbolic links only when you name them on the command line; -R follows every link it meets. Hidden files and folders are searched by -r like any others. --include and --exclude-dir make big searches much faster.

To combine grep with other file tests, such as "PHP files changed in the last day", use find:

bash
find ~/public_html -name '*.php' -mtime -1 -exec grep -Hn 'eval(' {} +

6. Log files

Compressed and rotated logs need zgrep, which takes the same options:

bash
zgrep -h ' 404 ' access.log.*.gz | wc -l

Useful one-liners for a web server access log in the common "combined" format:

bash
# Top 10 IP addresses by number of requests
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

# Top URLs returning 404 (field 9 is the status, field 7 the path)
awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn | head

# All requests from one IP in one hour
grep '^203\.0\.113\.7 ' access.log | grep '23/Sep/2026:14:'

# Login attempts on WordPress
grep -c 'POST /wp-login.php' access.log

Matching the status code with awk is more accurate than grep ' 404 ', which also matches a response size of 404 bytes.

7. Security checks on a website

grep is a quick first look when you suspect a hacked site. These patterns are common in injected PHP, but legitimate plugins use some of them too, so read each result before deleting anything:

bash
grep -rnE --include='*.php' 'eval\(|base64_decode\(|gzinflate\(|str_rot13\(' ~/public_html/
grep -rn --include='*.php' 'assert(\$_' ~/public_html/
find ~/public_html/wp-content/uploads -name '*.php'      # PHP files do not belong in uploads

For the full clean-up process, see Security checklist: what to do if your website has been hacked.

8. System logs on your own server

On a VPS where you are the administrator, where authentication failures are logged depends on the distribution: /var/log/auth.log on Debian and Ubuntu, /var/log/secure on AlmaLinux and Rocky Linux. Newer Debian releases log to the systemd journal by default instead, so pipe journalctl into grep:

bash
# Failed SSH logins, most frequent IPs first
journalctl -u ssh -u sshd --since today | grep -E 'Failed|Invalid user' \
  | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq -c | sort -rn | head

To block repeat offenders automatically, use a tool such as fail2ban or your firewall's own brute-force protection rather than a grep loop.

9. Faster alternatives

For large codebases, ripgrep (rg) is a popular alternative: it searches recursively by default, skips files listed in .gitignore, and is usually faster than grep. git grep searches only the files tracked in a Git repository. Both accept most of grep's options and regex syntax. grep remains the tool that exists on every Linux server.

10. Using grep on Domain India hosting

Jailed SSH access is available on every shared hosting plan (cPanel, DirectAdmin, Webuzo). It is off by default, so ask support to enable it; you then log in with an SSH key, not a password. See Enabling and accessing jailed SSH. Inside the jailed shell, grep searches the files in your own account, such as your website folders. Server-wide system logs are not part of your account.

On a VPS you have full root access and can search every log on the server. VPS hosting is self-managed and comes without a control panel. The card shows the live monthly price, excluding 18% GST.

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details
How do I search for text in all files in a folder with grep?

Use grep -r followed by the pattern and the folder, for example grep -rn 'text' /path/to/folder. Add --include='*.php' to limit the search to one file type, and -l to print only the names of the matching files.

How do I make grep ignore case?

Add the -i option, for example grep -i 'error' app.log. It then matches error, Error and ERROR.

What is the difference between grep -E and egrep?

They do the same thing: search with extended regular expressions, where +, ?, | and () work without backslashes. egrep is an obsolete name, and current GNU grep prints a warning when it is used, so write grep -E instead.

How do I show lines around a grep match?

Use -A N for N lines after the match, -B N for N lines before, or -C N for N lines on both sides, for example grep -C 3 'Exception' app.log.

How do I search compressed .gz log files?

Use zgrep, which works like grep on gzip-compressed files, for example zgrep 'error' access.log.1.gz. It accepts the same options as grep.

How do I search for text that contains special characters like dots or dollar signs?

Use grep -F, which treats the pattern as plain text instead of a regular expression, and put the pattern in single quotes so the shell does not change it.

Can I use grep on shared hosting?

Yes, once jailed SSH access is enabled on your account; ask Domain India support to switch it on. You can then search the files in your own account. Server-wide system logs are not available on shared hosting.

Ready to start searching? Get jailed SSH enabled on your hosting, or choose a VPS if you need root access to every log on the server.

Need full root access?

A self-managed Linux VPS with full root access and your choice of distribution.

See VPS plans

Ready when you are

Get DirectAdmin hosting from ₹100/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app