Can grep show only words that match search pattern?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Yes. Use grep -o to print only the matched text instead of the entire line. By default, grep outputs every line that contains a match. The -o flag changes this behavior so that each match is printed on its own line, with no surrounding context. Combined with -w for whole-word matching or -E for extended regex, grep -o covers most text extraction tasks directly from the command line.
Basic Usage: grep -o
The -o (or --only-matching) flag tells grep to output only the portion of each line that matches the pattern.
Output:
Without -o, grep would print the entire line. With -o, each match is isolated on its own line. If a single input line contains multiple matches, each one is printed separately.
Output:
This is useful for counting occurrences when combined with wc -l:
Whole-Word Matching: grep -ow
If you need to match complete words rather than substrings, add the -w flag. This prevents the pattern from matching inside longer words.
Output without -w:
The pattern matches cat inside scatter, catalog, and catfish. Adding -w restricts to whole words:
Output:
Only the standalone occurrences of cat are matched.
Extended Regular Expressions: grep -oE
The -E flag enables extended regular expressions, which support +, ?, |, and () without escaping. This is essential for most real-world extraction patterns.
Each of these prints only the matched token, one per line, ready for piping to sort, uniq, wc, or other tools.
Combining with Other Flags
grep -o works with most other grep options:
| Flag Combination | Purpose | Example |
-oi | Match only, case-insensitive | grep -oi 'error' app.log |
-ow | Match only, whole words | grep -ow 'cat' file.txt |
-oE | Match only, extended regex | grep -oE '[0-9]+' data.csv |
-oP | Match only, Perl regex (GNU grep) | grep -oP '(?<=id=)\d+' log |
-on | Match only, with line numbers | grep -on 'TODO' src/*.py |
-oc | Count matches per file | grep -oc 'error' *.log |
-oR | Match only, recursive search | grep -oR 'FIXME' src/ |
-oh | Match only, suppress filename | grep -ohR 'TODO' src/ |
Recursive Search with Filenames
Suppressing Filenames
Practical Examples
Counting Unique Matches
Extracting Version Numbers
Output:
Finding All Import Paths in JavaScript
Output:
Extracting JSON Keys
Building a Frequency Table
Output:
Perl-Compatible Regular Expressions: grep -oP
GNU grep supports Perl-compatible regular expressions (PCRE) with the -P flag. This adds support for lookahead, lookbehind, and non-capturing groups.
Output:
The (?<=id=) is a lookbehind assertion. It requires id= to precede the match but does not include it in the output. This is the closest grep gets to capture group extraction.
Output:
Note: -P is a GNU grep extension. It is not available on macOS grep by default. On macOS, install GNU grep via Homebrew (brew install grep) and use ggrep -oP.
When grep -o Is Not Enough
grep -o prints the entire match. It does not support printing only a capture group (a parenthesized subexpression). If you need to extract a specific part of a larger pattern, you have several options:
For more complex extractions, sed, awk, or perl are better tools:
Tool Comparison
| Capability | grep -o | grep -oP | sed | awk | perl |
| Print full match | Yes | Yes | Yes | Yes | Yes |
| Capture groups | No | Lookbehind only | Yes | Yes | Yes |
| Multiple captures per line | Yes (one per match) | Yes | Limited | Yes | Yes |
| Speed on large files | Fast | Fast | Moderate | Moderate | Moderate |
| Portability | All Unix | GNU only | All Unix | All Unix | Most Unix |
Common Pitfalls
- Forgetting
-oand getting full lines instead of just the matched text. This is the most common mistake. - Using a loose pattern that matches substrings inside larger words when
-wis needed.grep -o 'log'matches insideblog,catalog, andlogin. - Expecting
grep -oto print only a parenthesized capture group. It prints the entire regex match. Usegrep -oPwith lookbehind, or switch tosed/awk/perl. - Relying on
-P(Perl regex) in scripts that must run on macOS or BSD systems. The-Pflag is GNU-specific. Use-Efor portable scripts. - Writing an overly broad pattern that produces unexpected partial matches. For example,
grep -oE '[a-z]+'on English text prints every word as individual matches, which may not be the intent. - Forgetting that
-ochanges the output format when piping towc -l. Without-o,wc -lcounts matching lines. With-o, it counts individual matches, which can be higher.
Summary
grep -oprints only the matched text, not the full line. Each match appears on its own line.- Add
-wfor whole-word matching to prevent substring matches inside larger words. - Add
-Efor extended regex support (+,?,|,()without escaping). - Use
-Pwith lookbehind assertions for capture-group-like extraction (GNU grep only). - Combine
-owith-Rfor recursive search,-ifor case-insensitive matching, and-hto suppress filenames. - Switch to
sed,awk, orperlwhen you need to extract a specific subgroup from a larger match pattern.

