I don't understand what I'm missing here:

$ echo 'testing' | sed -E 's/([a-z]*)ing/\1ing/g'

I would expect the output to be testing again, since \1 should be test? That input seems to have been swallowed - i.e. the group matched it - but why is \1 not spitting it back out?

I am on macOS 10.12.2; using xonsh shell and GNU sed v4.3.


It turns out xonsh (or Python) is swallowing the \1, so sed actually sees 's/([a-z]*)ing/ing/g and its output is of course correct for that input.

I've opened an issue here about it, but the workaround is to use a Python raw string:

$ echo 'testing' | sed -E r's/([a-z]*)ing/\1ing/g'

This is preferable to escaping (\\1) since it would error in a POSIX shell rather than continue with the undesired \1.

However, with thanks to @adqm, double-quoting and also escaping the backslash is portable between xonsh and bash:

$ echo 'testing' | sed -E "s/([a-z]*)ing/\1ing/g"
  • I would have assumed it saw a 0x01 SOH byte, rather than nothing. (At least, that's what Python does) – Michael Homer Jan 15 '17 at 4:21
  • @MichaelHomer I don't really know, but: echo '\1' | hexdump: 0000000 01 0a [line end] 0000002 (under xonsh) – OJFord Jan 15 '17 at 5:17
  • Yes, that shows \1 is being interpreted as an octal escape for a byte 01, which sed will happily accept as part of the replacement. \\1 should work too then. – Michael Homer Jan 15 '17 at 5:52
  • @MichaelHomer Yes, \\1 is fine, less desirable because it doesn't error in POSIX shells (and continues with a literal \1). Maintainer pointed out in Github issue though that double-quoting and escaping ('s//\\1/') will work in both xonsh and bash. – OJFord Jan 15 '17 at 5:54

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.