I'm refactoring some code across lots of files, and am trying to do a search and replace using sed
on a Mac.
The goal is to go from this:
fooActions: typeof fooActionCreators
to this:
fooActions: Partial<typeof fooActionCreators>
I've gotten it to mostly work using this sed expression:
ag -l "Actions: typeof " | xargs sed -i "" -e "s/Actions: typeof \(\w*\)/Actions: Partial<typeof \1>/g"
Basically using ag
to find the list of file names containing a matching string, then use xargs
to pass those as input to my sed
expression.
The output I get though looks like this:
fooActions: Partial<typeof >fooActionCreators
I can't figure out why my capture group is being placed at then end instead of where I have it in the replace clause.
The sed that comes with mac doesn't support \w
for word characters.
If you have gsed (gnu sed) this should work as expected.
$ echo 'Actions: typeof foo' | gsed -e "s/Actions: typeof \(\w*\)/Actions: Partial<typeof \1>/g"
Actions: Partial<typeof foo>
Otherwise you can use something like [a-zA-Z]*
instead of \w*
.
$ echo 'Actions: typeof foo' | sed -e "s/Actions: typeof \([a-zA-Z]*\)/Actions: Partial<typeof \1>/g"
Actions: Partial<typeof foo>
The seemingly odd behavior that you're seeing is because in the plain sed version, the \w*
is matching the empty string in front of the thing you're hoping to match, as illustrated below:
Plain sed matches empty string in front of a
$ echo a | sed "s/\(\w*\)/\1x/"
xa
Gnu sed matches the a
as intended
$ echo a | gsed "s/\(\w*\)/\1x/"
ax