How to share a GNU sed script between Linux and Mac OS X
Solution 1
There are a few options:
- Use
#!/usr/bin/gsed -f
(assuming it is in/usr/bin
) as the shebang everywhere, and make sure that your Linux environments symlink this properly; - Remove the GNUisms;
- Symlink
sed
to/usr/bin/gsed
from a directory that earlier than/usr/bin
in the user's$PATH
(possibly dangerous); - Make a wrapper script that looks something like this:
#!/bin/sh
script=/foo
type gsed >/dev/null 2>&1 && exec gsed -f "$script"
exec sed -f "$script"
Ultimately there either need to be changes to at least one of the environments, or changes to the script itself.
Solution 2
You could have your sed
script start with this instead:
\:;s=sed;type gsed >/dev/null 2>&1 && s=gsed; exec "$s" -f "$0" "$@";$:s/^//
That's a no-op in sed
(though would slightly degrade your script performance) and when interpreted by a shell would execute with gsed
if found or sed
if not (both looked up in $PATH
).
Solution 3
(Giving an answer to my own question, or rather, an alternative approach that will work in this situation.)
A sed
script ascript.sed
, even when they start with a sha-bang, can also be applied from the command line on a target file target.txt
as sed -f ascript.sed target.txt
. This means that when on Mac OS X, one can call the script as gsed -f ascript.sed target.txt
.
Related videos on Youtube
equaeghe
Updated on September 18, 2022Comments
-
equaeghe over 1 year
I have a GNU
sed
script I use on Linux; it is installed at/bin/sed
and it seems it contains GNUisms. I have collaborators using Mac OS X. They have installed (non-GNU)sed
, located at/usr/bin/sed
, and using Homebrew (http://mxcl.github.io/homebrew/) can install GNUsed
asgsed
with the coreutils package, located at/usr/local/bin/gsed
.Currently, the script starts with
#!/bin/sed -f
. How do I modify it so that it can be run on Mac OS X, when GNUsed
is installed asgsed
?Another option would be to remove the GNUisms, but this may be a bit hard, as I do not have a Mac OS X install at hand and cannot ask my collaborators to test intermediate versions.
-
Jpark822 almost 11 yearsI have no OS X to test this on, but wouldn't
#!/usr/bin/env sed
work on both OS X and Linux? That would make things much more portable and it is the reason why env always should be used rather than fixed paths). -
equaeghe almost 11 years@Hennes: well, the problem is that on OS X, the
sed
I want would be calledgsed
, but your suggestion would work if the script does not contain any GNUisms.
-
-
equaeghe almost 11 yearsAh, would
\:;s=sed;command -v gsed >/dev/null && s=gsed; exec "$s" -f "$0" "$@";$:s/^//
then be more portable? -
equaeghe almost 11 yearsWould
\:;`command -v gsed || command -v sed` -f "$0" "$@";$:s/^//
be a portable alternative? -
Stéphane Chazelas almost 11 yearsI don't think
command -v
is significantly more portable thantype
. Both are optional in POSIX, required by Unix. Some old non-POSIX shells like variants of the Bourne shell, havetype
but notcommand -v
(though some older ones don't set the exit status to non-zero on command-not-found).posh
has neither. I once reported to the LSB that having neither was a problem, they acknowledged it, I though they did something about it, but now quickly looking at the latest spec, there doesn't seem to be anytype
orcommand
command (!?). -
Stéphane Chazelas almost 11 yearsCorrection. LSB now does mandate both
type
andcommand
(though I don't see that it says whether-v
should be supported). So it looks liketype
is required by the LSB, but (maybe) notcommand -v
.