Otto45
Otto45

Reputation: 595

sed replacement command not working on Mac

I'm trying to replace some text in a CMakelists.txt file with the value of a bash variable using sed, but I'm getting an error:

sed: 1: "'s/iPhone": invalid command code ?

sed command:

sed -i "" 's/iPhone Developer/'$PROVPROF'/g' CMakelists.txt

PROVPROF will always have something with this format:

iPhone Developer: Firstname Lastname (Numbers/Letters)

Upvotes: 9

Views: 18814

Answers (4)

krishnarajan s
krishnarajan s

Reputation: 41

With mytxt.txt containing:

hi soldiers

Working cmd:

sed -i '' "s/hi/hello/" mytxt.txt

It's worked for me 100% sure for mac users

follow this link https://singhkays.com/blog/sed-error-i-expects-followed-by-text/

Output:

hello soldiers

Upvotes: 4

mohamed chalal
mohamed chalal

Reputation: 141

The reason this doesn't work is because sed on linux is different that sed on mac. In order for your commands to work as intended, I recommend installing gnu-sed through homebrew.

You can do this via: brew install gnu-sed --with-default-names

NOTE: --with-default-names flag will attempt to symlink gnu-sed with your sed, should be what you want but if not, I warned you!

then run hash -r on bash, or rehash on zsh.

If it does not work after that, you must manually symlink gnu-sed with sed via:

ln -s /usr/local/bin/gsed $(which sed)

Upvotes: 14

konsolebox
konsolebox

Reputation: 75608

If you have characters in your variable which are the same as the delimiter you used to s, try using another delimiter instead:

sed -i '' "s|iPhone Developer|$PROVPROF|g" CMakelists.txt

Something more rare:

sed -i '' $'s\xFFiPhone Developer\xFF'"$PROVPROF"$'\xFFg' CMakelists.txt

Update:

Also, don't try to store your arguments on a variable. Word splitting would not always work the way you do. This is wrong:

command="sed -i '' 's|iPhone Developer|$PROVPROF|g' CMakelists.txt"
$command

Error message like sed: -e expression #1, char 1: unknown command: `'' would appear. On other seds the message may be different.

But you can use an array:

command=(sed -i '' "s|iPhone Developer|$PROVPROF|g" CMakelists.txt)
"${command[@]}"

It's still not commendable though. If you can run it directly, run it directly.

Upvotes: 6

Jan Nielsen
Jan Nielsen

Reputation: 11849

With file.txt containing:

Angelina used to like iPhone Developers.
Now she's more of an Android Developer fan-girl.

and Bash script like:

#!/bin/bash
#
#
export MONKEY_1="Billy Bob";
export MONKEY_2="Brad Pitt";

sed -e "s/iPhone Developer/$MONKEY_1/g" -e "s/Android Developer/$MONKEY_2/g" file.txt

running it yields:

Angelina used to like Billy Bobs.
Now she's more of an Brad Pitt fan-girl.

Upvotes: 0

Related Questions