I want to replace a?
with b?
where ?
is a character, not a wildcard. Here is what I tried:
echo "a?c" | sed 's/a\?/b?/'
I expect b?c
, but it returns b??c
. I also tried two backslashes between a
and ?
, it doesn't work either.
When not inside a bracket expression, the interpretation of an ordinary character preceded by an unescaped <backslash> is undefined, except for:
[...]
- The '?', '+', and '|' characters; it is implementation-defined whether "\?", "\+", and "\|" each match the literal character '?', '+', or '|', respectively, or behave as described for the ERE special characters '?', '+', and '|', respectively (see 9.4.3 ERE Special Characters).
Note: A future version of this standard may require "\?", "\+", and "\|" to behave as described for the ERE special characters '?', '+', and '|', respectively.
https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html#tag_09_03_02
When BRE is being used, to avoid ?
being treated as an ERE special character in implementations where \
turns it into one, don't use the backslash.
For portability, if you want to use ERE, invoke sed
with the -E
flag which allows use of ?
to mean zero-or-one and where escaping it with backslash has the effect you were expecting. (The BRE equivalent of ERE ?
is \{0,1\}
.)
To avoid ?
being treated as a metacharacter in either flavour, regardless of implementation, use a bracket expression: [?]