Skip to content

/flags/sed/sed-e-extended-regex

sed -E: use extended regular expressions (same as sed -r)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · sed (GNU sed) 4.9updated
tool
sed
command
sed
flag
-E, -r, --regexp-extended
default
off (basic regular expressions, BRE)

sed -E makes sed read patterns as extended regular expressions (ERE), so +, ?, |, ( ) and {n,m} are operators without backslashes. Without it, sed uses basic regular expressions (BRE), where those characters are literal and groups must be written \(...\). -r and --regexp-extended are GNU synonyms for -E; use -E, which also works with BSD sed on macOS.

Same substitution in BRE and ERE

bash
echo 'v1.22.3' | sed 's/\([0-9]*\)\.\([0-9]*\)/\2.\1/'
echo 'v1.22.3' | sed -E 's/([0-9]+)\.([0-9]+)/\2.\1/'
echo '--- + is literal without -E'
echo 'aaa+b' | sed 's/a+/X/'
echo 'aaa+b' | sed -E 's/a+/X/'
echo '--- alternation'
echo 'a|b' | sed 's/a|b/Z/'
echo 'a|b' | sed -E 's/a|b/Z/g'

Output

v22.1.3
v22.1.3
--- + is literal without -E
aaXb
X+b
--- alternation
Z
Z|Z

In basic mode a+ matched the two characters a+, so only the last a and the plus sign were replaced; with -E it matched aaa. The same happens with |: in BRE it is the pipe character.

What changes with -E

MeaningBRE (default)ERE (-E)
Group\( \)( )
One or more\+ (GNU only)+
Zero or one\? (GNU only)?
Alternation\| (GNU only)|
Repeat count\{2,4\}{2,4}
Literal parenthesis(\(
Literal plus sign+\+
Backreference in replacement\1\1

The flip side of -E is that characters which were literal now need escaping. A literal parenthesis in ERE must be \(, otherwise sed reports an error:

bash
echo '(x)' | sed -E 's/(/[/'

Output · exit 1

sed: -e expression #1, char 6: Unmatched ( or \(

GNU sed prints Unmatched ( or \( with the position in the expression. Escape it as s/\(/[/ in ERE, or drop -E for that command.

Typical uses

bash
printf '2026-10-24 ERROR disk full\n2026-10-24 INFO ok\n' > app.log
sed -E 's/^([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/' app.log
sed -nE '/ (ERROR|WARN) /p' app.log

Output

24.10.2026 ERROR disk full
24.10.2026 INFO ok
2026-10-24 ERROR disk full

Reformatting dates, extracting version numbers and filtering on several keywords are all shorter in ERE. Combined with -n and the p flag, sed -nE works like a grep that can also rewrite.

Pitfalls

  • Option order. -E affects every expression in the call, including those from -e and -f.
  • Shorthands are GNU only. \d does not exist in sed; \w, \s and \b are GNU extensions. Use [0-9], [[:space:]] and [[:alnum:]_] for portable scripts.
  • Combined flags. sed -Ei works on GNU sed; on macOS -i needs a suffix argument, see GNU vs BSD sed.
  • No lazy quantifiers. .*? is not supported in either mode; use a negated class such as [^"]*.

FAQ

What is the difference between sed -E and sed -r?

None in GNU sed: -r is the original GNU spelling and -E was added for compatibility with BSD sed. macOS sed has always used -E and older versions do not accept -r, so -E is the portable choice. POSIX added -E to sed in its 2024 edition.

Why does my sed regex with + or | not match anything?

Without -E, sed uses basic regular expressions, where +, ?, | and ( ) are literal characters. GNU sed accepts \+, \? and \| as operators in basic mode, but the portable fix is to add -E.

Do backreferences like \1 still work with -E?

Yes. Groups are written (...) instead of \(...\), and the replacement still refers to them as \1 to \9. Inside the pattern, backreferences in an ERE are a GNU extension.

Sources