Handling Cross-Platform sed Compatibility in Shell Scripts
When writing shell scripts that need to run across different operating systems, it’s important to consider platform-specific differences…
When writing shell scripts that need to run across different operating systems, it’s important to consider platform-specific differences. One such difference is how the sed (stream editor) command handles in-place editing.
The Issue with sed -i
The -i option in sed is used for in-place editing, meaning it modifies files directly instead of printing changes to standard output. However, its syntax differs between macOS and Linux (or Git Bash on Windows):
- Linux/Git Bash (Windows):
sed -i 's/old/new/g' file - macOS (BSD sed):
sed -i '' 's/old/new/g' file
On macOS, sed -i requires an additional argument specifying the extension for backup files. If no backup is needed, an empty string ('') must be provided. On Linux, sed -i works without an extra argument.
Writing a Cross-Platform Compatible Script
To ensure your script runs on both macOS and Linux/Git Bash, you can use a conditional check based on $OSTYPE:
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS
SED_CMD="sed -i ''"
else
# Linux/Git Bash (Windows)
SED_CMD="sed -i"
fiWith this setup, you can use $SED_CMD in your script for in-place modifications:
$SED_CMD 's/old/new/g' file.txtExplanation of the Code
- The script checks the
$OSTYPEvariable, which contains the operating system type. - If
$OSTYPEstarts withdarwin, it means the script is running on macOS, sosed -i ''is used. - Otherwise, it assumes Linux or Git Bash on Windows and uses
sed -iwithout an empty string.
Example Use Case
If you need to replace a word in a file across platforms, you can write a script like this:
#!/bin/bash
if [[ "$OSTYPE" == "darwin"* ]]; then
SED_CMD="sed -i ''"
else
SED_CMD="sed -i"
fi
# Replace 'foo' with 'bar' in sample.txt
$SED_CMD 's/foo/bar/g' sample.txtAlternative Approach Using gsed
For users who frequently work across platforms, installing GNU sed on macOS can simplify scripts. You can install it via Homebrew:
brew install gnu-sedThen use gsed instead of sed to ensure compatibility with Linux sed behavior:
gsed -i 's/old/new/g' file.txtConclusion
When writing shell scripts for cross-platform compatibility, always test commands like sed on different systems. Using an OS check with $OSTYPE or installing GNU tools can help maintain consistency and prevent unexpected errors.