A practical guide to regex syntax for BRE and ERE, covering anchors, quantifiers, character sets, and word boundaries for use in shell tools and scripts.
- Covers both Basic (BRE) and Extended (ERE) regex variants
- Ready-to-use patterns for
grep,egrep, and shell scripting - Side-by-side syntax comparison to avoid common pitfalls
- A Unix-like system (Linux, macOS, WSL)
grepavailable in$PATH(pre-installed on most systems)- Basic familiarity with the terminal
Regex has two main variants in Unix tools. Knowing which one your tool uses avoids silent errors.
| Variant | Command | Notes |
|---|---|---|
| BRE | grep |
Default; requires \ to activate {, (, | |
| ERE | grep -E or egrep |
Cleaner syntax; +, ?, |, () work natively |
Always use double quotes when writing regex patterns on the command line to prevent shell expansion.
grep "a" file.txt # matches the letter "a"grep "^start" file.txt # line starts with "start"
grep "end$" file.txt # line ends with "end"
grep "^$" file.txt # empty lines onlygrep "a.b" file.txt # any single character between a and b
grep "a.*b" file.txt # any sequence of characters between a and b (including empty)* is the only quantifier native to BRE. ? and + require ERE.
grep "ab*c" file.txt # zero or more "b" between a and cgrep "[abc]" file.txt # matches a, b, or c
grep "[a-z]" file.txt # any lowercase letter
grep "[A-Z]" file.txt # any uppercase letter
grep "[0-9]" file.txt # any digit
grep "[^abc]" file.txt # any character except a, b, or cBRE requires backslashes to activate grouping.
grep "\(foo\|bar\)" file.txt # matches "foo" or "bar" (BRE OR syntax)
grep "\(re\)*start" file.txt # zero or more repetitions of "re" before "start"grep "^$" file.txt # find all empty lines
grep "^[A-Z]" file.txt # lines starting with an uppercase letter
grep "[0-9][0-9][0-9]" file.txt # lines containing at least 3 consecutive digits
grep "\.[a-z]*$" file.txt # lines ending with a file extensionERE includes all BRE features with a simpler syntax and additional operators. Use grep -E or egrep.
grep -E "colou?r" file.txt # zero or one "u" - matches "color" and "colour"
grep -E "ab+" file.txt # one or more "b"
grep -E "ab*" file.txt # zero or more "b"grep -E "cat|dog" file.txt # matches "cat" or "dog"
grep -E "error|warn|fail" file.txt # matches any of the three wordsNo backslashes needed for grouping in ERE.
grep -E "(foo|bar)baz" file.txt # matches "foobaz" or "barbaz"
grep -E "(ha)+" file.txt # one or more repetitions of "ha"grep -E "a{3}" file.txt # exactly 3 "a"
grep -E "a{2,4}" file.txt # between 2 and 4 "a"
grep -E "a{2,}" file.txt # at least 2 "a"
grep -E "[0-9]{4}" file.txt # exactly 4 consecutive digits (e.g., year)
grep -E "[0-9]{2,3}" file.txt # 2 or 3 consecutive digitsgrep -E "\bword\b" file.txt # exact word match - avoids partial matches
grep -E "\b[pP]\w+\b" file.txt # all words starting with "p" or "P"
grep -E "\w+" file.txt # one or more alphanumeric characters or underscore\w is equivalent to [A-Za-z0-9_].
\b matches the boundary between a word character and a non-word character.
# Match an IP address pattern
grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" file.txt
# Match an email address pattern
grep -E "\w+@\w+\.[a-z]{2,}" file.txt
# Match lines with at least one word starting with a capital letter
grep -E "\b[A-Z]\w+" file.txt
# Match date format YYYY-MM-DD
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" file.txt
# Case-insensitive match with -i flag
grep -Ei "error" file.txt| Feature | BRE | ERE |
|---|---|---|
| Grouping | \(...\) |
(...) |
| OR operator | | |
| |
| Zero or one | not supported natively | ? |
| One or more | not supported natively | + |
| Repeat count | \{n,m\} |
{n,m} |
| Character class | [aeiou] |
[aeiou] |
| Alternation in group | \(a|e\) |
(a|e) |
Key rule: (a|e|i|o|u) requires ERE. Use [aeiou] for BRE compatibility - same result, simpler syntax.
grep -Eandegrepare equivalent - prefergrep -Efor portabilitygrep -imakes the match case-insensitive (works with both BRE and ERE)grep -vinverts the match - prints lines that do NOT matchgrep -oprints only the matched portion, not the full linegrep -nprefixes output with the line numbergrep -ccounts the number of matching lines
# Combine flags
grep -En "\b[A-Z]\w{4,}\b" file.txt # ERE, words starting uppercase, at least 5 chars
grep -iv "debug" app.log # case-insensitive, exclude lines with "debug"
grep -on "[0-9]+" file.txt # print only matched numbers, with line numbersCreated by Muller Matos