Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

grep searches input for lines containing a pattern and prints the matching lines. These 16 examples show how to choose literal matching, regular expressions, recursive searches, focused output, pipelines and safe handling of patterns that begin with a hyphen. The commands use GNU grep 3.12 syntax where noted; other Unix systems can provide different options.

Before you start: pattern, input and output

With no file argument, grep reads standard input. With one or more filenames, it searches those files. GNU grep uses basic regular expressions by default (also called -G). Use -F when the search text must be taken literally, and -E for extended regular expressions such as alternation. GNU -P requests PCRE-style matching, but it is not a portable default.

Quote patterns so the shell does not interpret characters such as *, $ or ^. Shell filename globs and grep regular expressions are separate syntaxes: *.c selects filenames in the shell, while an expression such as ^2026- is interpreted by grep.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find and refine matches in one file

1. Find a simple string

grep 'ERROR' app.log

This prints every line in app.log containing ERROR. Although the pattern is written as a literal-looking word, grep still treats it as a basic regular expression; it has no special characters here.

2. Ignore case

grep -i 'error' app.log

-i matches case variations such as Error, ERROR and error. Case conversion follows the locale in which grep runs, so results can differ for non-ASCII text.

3. Search punctuation literally

grep -F 'price: $5.00' app.log

-F disables regular-expression interpretation. It is the clearest choice for copied log snippets, user input and strings containing punctuation such as $, ., [ or *.

4. Match a whole word

grep -w 'cat' notes.txt

GNU grep’s -w requires the match to be bounded by its documented word-constituent rules, so cat does not match the substring in concatenate. This is not a universal linguistic word detector; test patterns containing punctuation or non-Latin text against your target implementation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Match either of two alternatives

grep -E 'ERROR|FATAL' app.log

-E enables extended regular expressions, making | alternation available without the extra escaping required by basic regular expressions. Quote the complete expression.

6. Match at the beginning of a line

grep '^2026-' app.log

The caret anchors the expression to the start of each line. Replace 2026- with the prefix relevant to your data, such as a log date, configuration key or record marker.

Change what grep prints

7. Add line numbers

grep -n 'timeout' app.log

-n prefixes each selected line with its 1-based line number. This is useful when opening the file in an editor, creating a bug report or locating a nearby configuration entry.

8. Print only the matching text

grep -oE '[0-9]{3}-[0-9]{4}' contacts.txt

With GNU grep, -o prints each nonempty matching portion on its own output line. Combined with -E, this extracts phone-number-shaped text rather than printing the surrounding sentence. It reports each match, not the entire input line.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

9. Count matching lines

grep -c 'WARN' app.log

-c prints the number of selected lines for each input file. If a line contains WARN three times, it still contributes one to the count; use -o and a downstream counter when you need occurrences instead of lines.

10. Exclude matching lines

grep -v 'DEBUG' app.log

-v inverts selection and prints lines that do not match. This is handy for removing routine noise before inspecting a log, but remember that blank lines and unrelated records remain in the output.

11. List only filenames that match

grep -l 'main' ./*.c

-l prints each filename as soon as grep finds a match and does not print matching content. The shell expands ./*.c before grep starts; if no file matches that glob, behavior depends on the shell’s unmatched-glob setting.

12. Show surrounding context

grep -C 2 'Exception' app.log

-C 2 shows two lines before and after each matching line, separated when nonadjacent context groups occur. Use -B 2 for preceding lines only or -A 2 for following lines only. Context is especially useful for stack traces and multi-line transactions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Search directories and command output

13. Search a directory tree recursively

grep -r -n 'TODO' ./project

-r descends through the directory tree and -n adds line numbers. GNU grep follows the recursion rules documented for that implementation; permissions, binary files and symbolic links can affect what is searched. Restrict the file set when a tree contains generated or vendor content.

14. Restrict recursive search to a file type

grep -r -n --include='*.c' 'main' ./src

GNU’s --include option limits recursive selection to names matching the supplied glob. The glob is a filename filter, not a grep regular expression. For multiple extensions, add additional include options or use find when you need precise predicates such as size, age, path or exclusion rules. Long options such as --include are GNU-specific; check the manual on non-GNU systems.

15. Filter another command’s output

journalctl -u example.service | grep -i 'failed'

The pipe sends standard output to grep, which prints lines containing failed in any case. journalctl is available on systemd-based systems; substitute a command appropriate to your platform. Add options to the producer when you need to control pagination, time range or output format before filtering.

Protect patterns and filenames that start with a hyphen

16. Safely search a variable pattern

grep -e "$pattern" ./*

-e explicitly marks the next argument as a pattern, so a value such as -n is not mistaken for an option. The ./ prefix keeps shell-expanded filenames from beginning with a hyphen. An option terminator, --, can also separate options from filenames, although a file literally named - has special standard-input meaning on many implementations. Quote variables and use ./filename paths whenever names are supplied by users.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Literal search or regular expression?

Need Use Why
Exact text copied from a log grep -F 'text' Punctuation is literal and no regex escaping is needed.
Simple pattern with basic syntax grep 'pattern' GNU grep defaults to basic regular expressions.
Alternation, repetition or grouping with extended syntax grep -E 'one|two' Uses extended regular expressions.
Recursive source search grep -r ... directory Traverses a directory tree; add GNU filters such as --include when appropriate.
Portable scripts POSIX options and documented expressions GNU extensions may not exist on BSD, macOS, BusyBox or other implementations.

Choose output options independently: combine -n with a normal search for locations, -l for a file inventory, -c for line counts, -o for extraction, and -C for diagnosis.

Exit statuses in scripts

GNU grep normally exits with status 0 when it selected at least one line, 1 when no line was selected, and 2 when an error occurred. “No match” is therefore different from a failed search. A script should test these outcomes deliberately rather than treating every nonzero status as an operational error.

if grep -q -F 'ready' app.log; then
    echo "ready"
elif [ "$?" -eq 1 ]; then
    echo "not found"
else
    echo "grep failed" >&2
    exit 2
fi

-q suppresses normal output and returns success as soon as a match is found. GNU documents a special case: with quiet mode, a match can produce status 0 even if an error was also detected. When using set -e, handle the expected status-1 “no match” branch explicitly so a normal negative result does not abort the script.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common grep problems

Special characters match unexpectedly

Use -F for literal text, or escape regex metacharacters. Keep the pattern in single quotes unless shell variable expansion is required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A filename is treated as an option

Prefix paths with ./, use -- before filenames, and use -e before a pattern that may begin with -.

Recursive search is too broad or misses files

Add GNU --include or --exclude rules, or compose find with grep for exact path and file predicates. Check permissions and whether the files are binary.

The command works on Linux but not elsewhere

Options such as --include and -P are not guaranteed by POSIX. Consult the target system’s grep manual and prefer POSIX options when distributing scripts.

“No matches” looks like an error

Check the exit status: 1 means no selected lines, while 2 indicates an error. In pipelines, remember that the shell’s pipeline status rules may hide an earlier command’s failure unless you enable the shell’s pipeline-status feature.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If your workflow ultimately needs a rendered image of a web page rather than text matching, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; only clean shots are billed. Bot checks, blank pages, timeouts, failed loads and cache hits cost nothing, and response headers identify the page verdict and billing result.

One GET request returns PNG, JPEG, WebP or PDF. See the ScreenshotNeo documentation for all options, including full-page and element capture, device presets, custom CSS and JavaScript, waits, blocking rules, cookies, headers, geolocation, caching, signed links, asynchronous jobs and bulk capture.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

An MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free for ScreenshotNeo.

Frequently Asked Questions

Does grep search inside each line or return whole lines?

Normal grep selection returns the complete lines containing a match. Use GNU -o when you need only the matching portions.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What is the difference between -r and -R?

This article uses -r, the recursive option documented for GNU grep. Follow-link behavior and the availability of -R vary by implementation, so consult the grep manual on the target system.

Can grep search binary files?

Behavior for binary data is implementation- and option-dependent. If binary files are possible, review GNU grep’s binary-file options or restrict the search to known text files.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.