8

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 GNU sed as gsed 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 GNU sed is installed as gsed?

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.

2
  • 1
    I 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).
    – Hennes
    Commented May 14, 2013 at 10:15
  • @Hennes: well, the problem is that on OS X, the sed I want would be called gsed, but your suggestion would work if the script does not contain any GNUisms.
    – equaeghe
    Commented May 15, 2013 at 8:40

3 Answers 3

6

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.

5

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

4
  • Ah, would \:;s=sed;command -v gsed >/dev/null && s=gsed; exec "$s" -f "$0" "$@";$:s/^// then be more portable?
    – equaeghe
    Commented May 15, 2013 at 9:01
  • Would \:;`command -v gsed || command -v sed` -f "$0" "$@";$:s/^// be a portable alternative?
    – equaeghe
    Commented May 15, 2013 at 9:11
  • 1
    I don't think command -v is significantly more portable than type. Both are optional in POSIX, required by Unix. Some old non-POSIX shells like variants of the Bourne shell, have type but not command -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 any type or command command (!?). Commented May 15, 2013 at 9:40
  • 1
    Correction. LSB now does mandate both type and command (though I don't see that it says whether -v should be supported). So it looks like type is required by the LSB, but (maybe) not command -v. Commented May 15, 2013 at 9:46
1

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .