this has been bugging me for a couple years now.

"match this or that" works.
"match beginning of line" works.
"match end of line" works.
"match beginning of line or end of line", not so much.

All on MacOS.

echo "hello world" | sed -E 's/(h|d)/X/g'
Xello worlX

echo "hello world" | sed -E 's/(^)/X/g'
Xhello world

echo "hello world" | sed -E 's/($)/X/g'
hello worldX

echo "hello world" | sed -E 's/(^|$)/X/g'
Xhello world
  • 1
    What's your question then? "Why?", "how to make it work?", "is it a bug?" Or what? Apr 1, 2019 at 21:15
  • 2
    For comparison: the last command yields Xhello worldX on Debian. Apr 1, 2019 at 21:19

1 Answer 1


This may be a bug in MacOS' sed implementation.

Your syntax works for me under FreeBSD 12 and Ubuntu 18:

$ sed -E 's/(^|$)/X/g'
Xhello worldX

Perhaps this work-around will suffice for your needs until the bug is addressed:

$ echo "hello world" | sed -E -e 's/^/X/' -e 's/$/X/'
Xhello worldX

Given your comment regarding a complex replacement string, the above can be generalized a little more, at the expense of a little more complexity:

$ X='replacement text here'
$ printf "echo 'hello world' | sed -E -e 's/^/%s/' -e 's/$/%s/'" "$X" "$X" | sh 
replacement text herehello worldreplacement text here
  • thanks Jim. yep, i've been doing the dual -e's. it's not a huge hassle just a minor gripe when the replacement is a bit more involved than X. Apr 1, 2019 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.