Grep Regex: Regular Expressions Syntax and Examples

By 

Updated on

10 min read

Grep regular expressions

Regular expressions (regex) are patterns that describe sets of strings. They are one of the most powerful features of the grep command, allowing you to search for complex text patterns rather than simple fixed strings.

This guide covers how to use regular expressions with the GNU version of grep, which is available by default on most Linux distributions.

Grep Regular Expression Syntax

A regular expression consists of literal characters and meta-characters that have special meaning. GNU grep supports three regular expression syntaxes:

  • Basic Regular Expressions (BRE): the default. Meta-characters ?, +, {, |, (, and ) are treated as literal characters. To use their special meaning, escape them with a backslash (\).
  • Extended Regular Expressions (ERE): enabled with -E (or --extended-regexp). The same meta-characters work without escaping.
  • Perl-Compatible Regular Expressions (PCRE): enabled with -P (or --perl-regexp). Supports advanced features such as lookaheads, lookbehinds, and non-greedy quantifiers.

In GNU grep, BRE and ERE are functionally identical. The only difference is whether meta-characters need to be escaped. PCRE adds features that neither BRE nor ERE support.

You should always enclose the regular expression in single quotes to prevent the shell from interpreting the meta-characters:

Terminal
grep 'pattern' file.txt

Literal Matches

The most basic usage of grep is to search for a literal character or series of characters in a file. For example, to display all lines containing the string “bash” in the /etc/passwd file:

Terminal
grep bash /etc/passwd
output
root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

In this example, “bash” is a basic regular expression consisting of four literal characters. The grep command searches for a “b” immediately followed by “a”, “s”, and “h”.

By default, grep is case-sensitive. Use the -i option to ignore case. Note that grep searches for patterns, not whole words, so searching for “gnu” will also match “cygnus” and “magnum”. Use the -w option to match whole words only.

If the search string includes spaces, enclose it in single or double quotation marks:

Terminal
grep "Gnome Display Manager" /etc/passwd

Anchoring

Anchors are meta-characters that allow you to specify where in the line the match must be found.

The ^ (caret) symbol matches the beginning of a line. In the following example, the string “linux” matches only if it occurs at the very beginning of a line:

Terminal
grep '^linux' file.txt

The $ (dollar) symbol matches the end of a line. The following matches lines that end with “linux”:

Terminal
grep 'linux$' file.txt

You can combine both anchors. For example, to find lines that contain only the word “linux”:

Terminal
grep '^linux$' file.txt

The ^$ pattern matches all empty lines, which is useful for filtering them out with grep -v '^$'.

Matching Single Characters

The . (period) symbol is a meta-character that matches any single character. For example, to match anything that begins with “kan”, then has two characters, and ends with “roo”:

Terminal
grep 'kan..roo' file.txt

This would match “kangaroo”, “kaneiroo”, or any other five-letter combination between “kan” and “roo”.

Bracket Expressions

Bracket expressions allow you to match any single character from a group by enclosing the characters in brackets []. For example, to find lines that contain “accept” or “accent”:

Terminal
grep 'acce[np]t' file.txt

If the first character inside the brackets is the caret ^, it matches any single character not in the set. The following pattern matches strings like “coca” or “coma”, but not “cola”:

Terminal
grep 'co[^l]a' file.txt

Character Ranges

Instead of listing characters one by one, you can specify a range separated by a hyphen. For example, [a-e] is equivalent to [abcde] and [1-3] is equivalent to [123].

The following expression matches each line that starts with a capital letter:

Terminal
grep '^[A-Z]' file.txt

POSIX Character Classes

grep supports predefined character classes enclosed in [: and :]. These must be used inside brackets, so the full syntax is [[:class:]]:

ClassDescription
[:alnum:]Alphanumeric characters.
[:alpha:]Alphabetic characters.
[:blank:]Space and tab.
[:digit:]Digits.
[:lower:]Lowercase letters.
[:upper:]Uppercase letters.
[:space:]Whitespace characters.
[:punct:]Punctuation characters.

For example, to match lines that start with a digit:

Terminal
grep '^[[:digit:]]' file.txt

To match lines containing only alphabetic characters:

Terminal
grep '^[[:alpha:]]*$' file.txt

For a complete list of all character classes, see the Grep manual .

Quantifiers

Quantifiers specify how many times the preceding item must occur for a match. The following table shows the quantifiers supported by GNU grep:

QuantifierDescription
*Match the preceding item zero or more times.
?Match the preceding item zero or one time.
+Match the preceding item one or more times.
{n}Match the preceding item exactly n times.
{n,}Match the preceding item at least n times.
{,m}Match the preceding item at most m times.
{n,m}Match the preceding item from n to m times.

The * (asterisk) character matches the preceding item zero or more times. The following will match “right”, “sright”, “ssright”, and so on:

Terminal
grep 's*right' file.txt

The .* combination matches any number of any characters. The following matches all lines that start with a capital letter and end with a period or comma:

Terminal
grep -E '^[A-Z].*[.,]$' file.txt

The ? (question mark) character makes the preceding item optional, matching it zero or one time. The following matches both “bright” and “right”. When using basic regular expressions, the ? must be escaped:

Terminal
grep 'b\?right' file.txt

Here is the same regex using extended regular expressions:

Terminal
grep -E 'b?right' file.txt

The + (plus) character matches the preceding item one or more times. The following will match “sright” and “ssright”, but not “right”:

Terminal
grep -E 's+right' file.txt

The brace characters {} allow you to specify the exact number or a range of occurrences. The following matches all integers that have between 3 and 9 digits:

Terminal
grep -E '[[:digit:]]{3,9}' file.txt

Alternation

The alternation operator | (pipe) allows you to specify different possible matches, functioning as a logical “OR”. It has the lowest precedence of all regular expression operators.

In the following example, we search for all occurrences of the words “fatal”, “error”, and “critical” in the Nginx log error file:

Terminal
grep 'fatal\|error\|critical' /var/log/nginx/error.log

If you use extended regular expressions with -E, the | operator does not need to be escaped:

Terminal
grep -E 'fatal|error|critical' /var/log/nginx/error.log

Grouping

Grouping allows you to combine patterns together and reference them as a single item. Groups are created using parentheses ().

When using basic regular expressions, the parentheses must be escaped with a backslash (\).

The following example matches both “fearless” and “less”. The ? quantifier makes the (fear) group optional:

Terminal
grep -E '(fear)?less' file.txt

Groups are also useful with alternation. The following matches “cat” or “car”:

Terminal
grep -E 'ca(t|r)' file.txt

Escaping Special Characters

To match a meta-character literally, you must escape it with a backslash (\). This is a common source of confusion when searching for characters like ., *, [, ?, or $ in text.

For example, to search for a literal dot:

Terminal
grep '192\.168\.1\.1' file.txt

Without the backslashes, the . would match any character, so “192.168.1.1” would also match “192x168y1z1”.

To search for a literal asterisk:

Terminal
grep '\*' file.txt

Alternatively, you can use the -F option (or --fixed-strings) to treat the entire pattern as a literal string, disabling all regex interpretation:

Terminal
grep -F '192.168.1.1' file.txt

Special Backslash Expressions

GNU grep includes several meta-characters that consist of a backslash followed by a regular character:

ExpressionDescription
\bMatch a word boundary.
\<Match the beginning of a word.
\>Match the end of a word.
\wMatch a word character ([a-zA-Z0-9_]).
\WMatch a non-word character.
\sMatch a whitespace character such as a space or tab.
\SMatch a non-whitespace character.

The \b expression is useful for matching whole words without the -w option. The following pattern matches the separate words “abject” and “object” but will not match them if embedded in larger words:

Terminal
grep '\b[ao]bject\b' file.txt

You can use the same boundary pattern with other character sets. For example, to match lines containing a separate three-digit number:

Terminal
grep '\b[0-9]\{3\}\b' file.txt

Perl-Compatible Regular Expressions

The -P option enables Perl-compatible regular expressions (PCRE), which support advanced features not available in BRE or ERE.

Lookaheads match a pattern only if it is followed by (or not followed by) another pattern, without including the second pattern in the match. For example, to match “error” only if it is followed by a colon:

Terminal
grep -P 'error(?=:)' file.txt

To match “error” only if it is not followed by a colon (negative lookahead):

Terminal
grep -P 'error(?!:)' file.txt

Lookbehinds work in the opposite direction. To match a number only if it is preceded by a dollar sign:

Terminal
grep -P '(?<=\$)[0-9]+' file.txt

Non-greedy quantifiers match as few characters as possible. Add ? after a quantifier to make it non-greedy:

Terminal
grep -P '<.*?>' file.txt

This matches the shortest possible string between < and >, rather than the longest.

Info
The -P option is not available in all grep implementations. It is supported by GNU grep on most Linux distributions.

Practical Regex Examples

Below are a few real-world patterns you can copy and adapt. Each example uses the extended syntax (-E) and the -o option to print only the matching portion of each line, which is convenient when you want to extract values rather than full lines.

To extract IPv4 addresses from a log file:

Terminal
grep -E -o '([0-9]{1,3}\.){3}[0-9]{1,3}' /var/log/syslog

This pattern matches any four groups of one to three digits separated by dots. It does not strictly validate octets above 255, but it is enough for most log-scraping tasks.

To extract email addresses from a text file:

Terminal
grep -E -o '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b' file.txt

The \b word boundaries prevent the pattern from matching email-like substrings embedded inside larger tokens.

To extract hex color codes (such as #ffcc00) from a CSS file:

Terminal
grep -E -o '#[0-9A-Fa-f]{6}\b' styles.css

The pattern matches a # followed by exactly six hexadecimal characters.

To extract ISO-style dates (such as 2026-05-17) from any file:

Terminal
grep -E -o '[0-9]{4}-[0-9]{2}-[0-9]{2}' file.txt

Use -h if you are searching multiple files and want only the dates without the filename prefix.

To extract URLs that start with http or https:

Terminal
grep -E -o 'https?://[^[:space:]]+' file.txt

The pattern stops at the first whitespace character, which works well for plain text files and most log formats.

Quick Reference

For a printable quick reference, see the Grep cheatsheet .

PatternDescription
.Any single character
^Start of line
$End of line
[abc]Any character in set
[^abc]Any character not in set
[a-z]Any character in range
*Zero or more of preceding
+One or more of preceding (ERE)
?Zero or one of preceding (ERE)
{n}Exactly n of preceding (ERE)
{n,m}Between n and m of preceding (ERE)
\bWord boundary
\wWord character
\sWhitespace character
|Alternation / OR (BRE)
\(\)Grouping (BRE)
\Escape next character

FAQ

What is the difference between basic and extended regular expressions?
The two syntaxes are functionally identical in GNU grep. The only difference is that in basic regular expressions (BRE), the meta-characters ?, +, {, |, (, and ) must be escaped with a backslash to use their special meaning. In extended regular expressions (ERE, enabled with -E), these characters are special by default.

How do I match a literal dot or other special character?
Escape the character with a backslash. For example, use \. to match a literal dot, \* for a literal asterisk, and \[ for a literal bracket. Alternatively, use grep -F to disable regex entirely and treat the pattern as a fixed string.

What does the -P option do?
The -P option enables Perl-compatible regular expressions (PCRE), which support advanced features such as lookaheads ((?=...)), lookbehinds ((?<=...)), and non-greedy quantifiers (*?, +?). These features are not available in basic or extended regular expressions.

How do I match the beginning or end of a word?
Use \b for a word boundary, \< for the beginning of a word, or \> for the end of a word. For example, grep '\bword\b' file.txt matches “word” as a whole word. You can also use grep -w "word" for the same effect.

How do I match whitespace with grep?
Use the \s shorthand to match whitespace such as spaces and tabs in GNU grep, or the POSIX class [[:space:]] for portability. To match one or more whitespace characters, use grep -E '\s+' file.txt or grep '[[:space:]]\+' file.txt. To find blank or whitespace-only lines, use grep -E '^[[:space:]]*$' file.txt.

Conclusion

Regular expressions are used in text editors, programming languages, and command-line tools such as grep , sed , and awk . Knowing how to construct regular expressions is essential for searching text files, writing scripts, and filtering command output.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

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