331

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.

Paul Wintz
  • 2,542
  • 1
  • 19
  • 33
helion3
  • 34,737
  • 15
  • 57
  • 100

6 Answers6

785

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.

Community
  • 1
  • 1
damienfrancois
  • 52,978
  • 9
  • 96
  • 110
  • 1
    The example command you give however, gives: sed: RE error: illegal byte sequence – helion3 Oct 18 '13 at 19:38
  • That most probably is a copy-paste encoding problem as it works with no problem in my tests. See [this](http://stackoverflow.com/questions/11287564/getting-sed-error-illegal-byte-sequence-in-bash) – damienfrancois Oct 18 '13 at 19:46
  • 71
    If you spent 10 min like I did finding the difference, it is -e option – acheron55 May 07 '14 at 15:18
  • @acheron55 I updated my answer to be explicitly about the `-e` option – damienfrancois May 13 '14 at 06:15
  • 13
    [This question](http://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac-os-x) answers the `RE error: illegal byte sequence` on MacOS. – JonasVautherin Jul 01 '14 at 20:00
  • 15
    i used an empty string '' as the parameter for -i and that worked, like `sed -i '' 's/blah/xx/g'` – Pierre Houston Aug 29 '14 at 08:59
  • 29
    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. – mdup Oct 02 '14 at 08:51
  • 1
    I definitely am on OS X default sed, not homebrew'd. Mavericks 10.9.3 (maybe sed differs with OS X versions?). No worries, I've added the answer I'd like to have had (and I guess it would have solved the OP's problem as well). – mdup Oct 02 '14 at 11:17
  • 6
    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`. – aspyct Dec 30 '14 at 15:20
  • Same here, using the sed that ships with 10.10. I recommend `-i ''` – Joost Sep 30 '15 at 18:09
  • I find it funny how you [edited your answer](http://stackoverflow.com/posts/19457213/revisions) to make it look like mine :) Anyway, as long as users solve their problems, I don't care. Cheers! – mdup Jun 20 '16 at 14:06
  • @mdup I updated my answer after your comment, which I could not verify on my system, but which was backed up by several other commenters. My edit dates Oct 1 '15 at 4:44 and your answer is dated Oct 2 '14 at 8:54. Cheers. – damienfrancois Jun 21 '16 at 07:33
  • You can solve this, and all the other problems with macOS, by installing Gnu versions of everything – JDS May 17 '17 at 19:20
  • A working revised answer on OSX is: find ./ -type f -exec sed -ie "s/192.168.20.1/new.domain.com/" {} \; – Darrell Teague Aug 02 '17 at 18:55
  • 1
    is there a version where the same command would work for both OS X and Linux? – bentael Oct 29 '17 at 12:01
  • 2
    @bentael Using [Homebrew](https://brew.sh) on OS X you can install the GNU `sed` which is the one installes on Linux. – damienfrancois Oct 30 '17 at 07:09
  • 1
    @bentael if you don't want to install an alternative `sed` see https://stackoverflow.com/questions/5694228/sed-in-place-flag-that-works-both-on-mac-bsd-and-linux#comment85499736_22084103 – Jaime Hablutzel Jan 24 '21 at 19:22
  • 1
    Why is this upvoted 578 times? Creates many backup files ending in ".oldext-e" – Tom Grushka Apr 03 '21 at 21:34
  • Thank youuuu! Been trying to write a script for generating an app and have been searching around for the past couple of hours for this. – Hamza A.Malik May 12 '21 at 20:57
97

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.

Dmitry Mikushin
  • 1,478
  • 15
  • 16
  • 4
    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. – Stephen Shank May 14 '20 at 23:10
  • 14
    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. – Jeppe Gravgaard Feb 17 '21 at 12:14
67

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.

mdup
  • 7,889
  • 3
  • 32
  • 34
5

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

Moza Man
  • 51
  • 1
  • 1
3

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.

Ricardo Gonçalves
  • 4,344
  • 2
  • 20
  • 30
  • 1
    The OS generally does no such thing. Did you copy/paste from a blog or a word processor or something? – tripleee May 24 '22 at 11:47
  • @tripleee you're right! Updated my answer. – Ricardo Gonçalves May 24 '22 at 20:23
  • 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. – tripleee May 25 '22 at 05:34
  • (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.) – tripleee May 25 '22 at 05:37
2

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

jkshah
  • 11,387
  • 6
  • 35
  • 45