1

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.

Danny Delott
  • 6,756
  • 3
  • 33
  • 57

2 Answers2

1

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
jas
  • 10,715
  • 2
  • 30
  • 41
0

if your data in 'd' file, by gnu sed,

sed -E 's/^(fooAction)s: (typeof \1Creators)/\1s: Partial<\2>/' d