Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

linux

macos

sed

bsd

People also ask

Does sed work in Macos?

One way to make the GNU version of the SED to work on the Mac OS X, is to directly install the gnu-sed along with the default names which will assure you that you won't have to run different commands on both the operating systems.

Is Macos based on Linux or BSD?

You may have heard that Macintosh OSX is just Linux with a prettier interface. That's not actually true. But OSX is built in part on an open source Unix derivative called FreeBSD.

What is sed command Mac?

SED is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). While in some ways similar to an editor which permits scripted edits, SED works by making only one pass over the input(s), and is consequently more efficient.


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.


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 ''.

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

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.