Portable sed -i across MacOS and Linux
The -i flag to ask sed to edit a file in place works differently on Linux and MacOS. If you want to create a backup of your file before you edit it, say with the extension .bak, then on Linux you would run
sed -i.bak myfile
but for the version of sed that ships with MacOS you would write
sed -i '.bak' myfile
Note that this changes how sed interprets its arguments, whether you want a backup file or not. You must specify a backup file extension, but could specify the extension as '', which effectively means don't make a backup.
The difference between how the two versions of sed handle their arguments is a minor nuisance when working interactively at the command line, but a script calling sed -i will not work the same on Mac and Linux.
I put the line
alias sed=gsed
in my .zshrc file so that when I type sed the shell will actually run the Gnu version of sed, which handles -i as I expect.
But this does not work in bash scripts. I tried putting the alias in my .bashrc and .bash_profile files, but that doesn't work. In scripts bash ignores aliases, no matter what config file you put them in. Here's the relevant line from the bash man page:
Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt.
So the solution is to put the magic incantation
shopt -s expand_aliases
at the top of your script.
Here's how I wrote a script using sed -i works the same way on MacOS and Linux.
#!/usr/bin/env bash shopt -s expand_aliases if [[ "$OSTYPE" == "darwin"* ]]; then alias sed=gsed fi sed -i ...
This may seem a little heavy-handed, changing the program that I'm using just to fix a problem with the arguments. I could, for example, have the script insert '' after -i when running on MacOS.
But I'm not changing the program I use. Quite the opposite. The code above saves me from having to use a different program. It insures that I'm running the Gnu version of sed on both platforms. There are other differences between the two versions of sed. I don't know what they are off hand, but they could lead to frustrating bugs in the future, and the code above fixes these bugs before they occur.
The post Portable sed -i across MacOS and Linux first appeared on John D. Cook.