sed in-place flag that works both on Mac (BSD) and Linux

When on OSX, I always install GNU sed version via Homebrew, to avoid problems in scripts, because most scripts were written for GNU sed versions.

brew install gnu-sed --with-default-names

Then your BSD sed will be replaced by GNU sed.

Alternatively, you can install without default-names, but then:

  • Change your PATH as instructed after installing gnu-sed
  • Do check in your scripts to chose between gsed or sed depending on your system

This works with GNU sed, but not on OS X:

sed -i -e 's/foo/bar/' target.file
sed -i'' -e 's/foo/bar/' target.file

This works on OS X, but not with GNU sed:

sed -i '' -e 's/foo/bar/' target.file

On OS X you

  • can't use sed -i -e since the extension of the backup file would be set to -e
  • can't use sed -i'' -e for the same reasons—it needs a space between -i and ''.

If you really want to just use sed -i the 'easy' way, the following DOES work on both GNU and BSD/Mac sed:

sed -i.bak 's/foo/bar/' filename

Note the lack of space and the dot.

Proof:

# GNU sed
% sed --version | head -1
GNU sed version 4.2.1
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file  file.bak
% cat ./file
bar

# BSD sed
% sed --version 2>&1 | head -1
sed: illegal option -- -
% echo 'foo' > file
% sed -i.bak 's/foo/bar/' ./file
% ls
file  file.bak
% cat ./file
bar

Obviously you could then just delete the .bak files.


As Noufal Ibrahim asks, why can't you use Perl? Any Mac will have Perl, and there are very few Linux or BSD distributions that don't include some version of Perl in the base system. One of the only environments that might actually lack Perl would be BusyBox (which works like GNU/Linux for -i, except that no backup extension can be specified).

As ismail recommends,

Since perl is available everywhere I just do perl -pi -e s,foo,bar,g target.file

and this seems like a better solution in almost any case than scripts, aliases, or other workarounds to deal with the fundamental incompatibility of sed -i between GNU/Linux and BSD/Mac.

Tags:

Linux

Macos

Sed

Bsd