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