ChatGPT解决这个技术问题 Extra ChatGPT

Error when using 'sed' with 'find' command on OS X: "invalid command code ."

Being forced to use CVS for a current client and the address changed for the remote repo. The only way I can find to change the remote address in my local code is a recursive search and replace.

However, with the sed command I'd expect to work:

find ./ -type f -exec sed -i "s/192.168.20.1/new.domain.com/" {} \;

I get an error for every file:

sed: 1: ".//file/path ...": invalid command code .

I've tried to escape the periods in the sed match/replacement but that doesn't solve anything.


C
Community

If you are on a OS X, this probably has nothing to do with the sed command. On the OSX version of sed, the -i option expects an extension argument so your command is actually parsed as the extension argument and the file path is interpreted as the command code.

Try adding the -e argument explicitly and giving '' as argument to -i:

find ./ -type f -exec sed -i '' -e "s/192.168.20.1/new.domain.com/" {} \;

See this.


If you spent 10 min like I did finding the difference, it is -e option
This question answers the RE error: illegal byte sequence on MacOS.
i used an empty string '' as the parameter for -i and that worked, like sed -i '' 's/blah/xx/g'
For me, adding -e after -i made sed backup all my files in this way: "foo.txt" -> "foo.txt-e". Obviously what I wanted was rather -i '', i.e. don't backup changed files.
Same problem for me. This -i -e combined with a find resulted in many many files ending in -e-e-e-e-e-e-e.
D
Dmitry Mikushin

On OS X nothing helps poor builtin sed to become adequate. The solution is:

brew install gnu-sed

And then use gsed instead of sed, which will just work as expected.


Thank you for this answer, which worked great for me! Working on both Linux and Mac, I'd much prefer access to a familiar tool than learning arcane differences between two closely related ones.
Thanks - worked for me too. A nice little tip is to set up an alias like alias sed='gsed' to make the alignment between macOS and linux complete.
m
mdup

You simply forgot to supply an argument to -i. Just change -i to -i ''.

Of course that means you don't want your files to be backed up; otherwise supply your extension of choice, like -i .bak.


M
Moza Man

Simply add an extension to the -i flag. This basically creates a backup file with the original file.

sed -i.bakup 's/linenumber/number/' ~/.vimrc

sed will execute without the error


j
jkshah

Probably your new domain contain / ? If so, try using separator other than / in sed, e.g. #, , etc.

find ./ -type f -exec sed -i 's#192.168.20.1#new.domain.com#' {} \;

It would also be good to enclose s/// in single quote rather than double quote to avoid variable substitution or any other unexpected behaviour


R
Ricardo BRGWeb

It is not the case for the OP but it was for me and could help someone else.

If you are using ' to enclose regex, double check the ' characters. I was copying and pasting the script from word processing and it was pasting ' as in bash.


The OS generally does no such thing. Did you copy/paste from a blog or a word processor or something?
@tripleee you're right! Updated my answer.
So the real lesson here is never use a word processor for code. There are some blog platforms which unfortunately apply "styling" to code and thus breaking it, which you as a consumer of that blog can't really do much about.
(Also, irritatingly, the keyboard substitution facility on IOS will "helpfully" replace ASCII quotes with "typographic" ones no matter what you do, so it's not great for saving snippets of code.)