To complement the sed -E
solution in anubhava's answer with a fixed version of your own solution attempt:
sed 's/\([a-zA-Z0-9]\{1,\}\)-\([a-zA-Z0-9]\{1,\}\)/\1 @-@ \2/g' test.txt > test2.txt
That is, the ERE (extended regex) quantifier construct +
must be emulated with \{1,\}
in a BRE (basic regex), which sed
uses by default.
Optional background information
As Sundeep points in out in a comment on the question, GNU sed
allows use of \+
(when not using -r
/ -E
, which enables support for EREs), but that is a nonstandard extension not supported by the macOS sed
version.
The sed
POSIX spec only supports BREs, specifically, POSIX BREs.
Therefore, to write portable sed
commands:
Use neither -r
(GNU sed
an more recent versions of BSD sed
) nor -E
(both GNU and BSD/macOS sed
)
Use only POSIX BRE features, avoiding implementation-specific extensions, notably:
- Use
\{1,\}
instead of \+
(the equivalent of ERE +
).
- Use
\{0,1\}
instead of \?
(the equivalent of ERE ?
).
- Avoid GNU's
\|
for alternation: unfortunately, POSIX BREs do not support alternation at all.
To take advantage of the more powerful, modern-syntax EREs while supporting platforms with both GNU and BSD sed
(including macOS):
To learn about a given sed
implementation's specific (nonstandard) regex features:
GNU Sed (Linux):
info sed
, as of GNU Sed 4.2.2, explains
(By contrast, man re_format
/ man 7 regex
contain only POSIX info.)
BSD / macOS Sed:
man re_format
does apply (discusses both BREs and EREs), except for the section about enhanced features, which aren't supported.
- The only extensions mentioned are word-boundary assertions
[[:<:]]
and [[:>:]]
For a comprehensive overview of all differences between GNU Sed and BSD Sed, see this answer of mine.