How to share a GNU sed script between Linux and Mac OS X

6,476

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.

Share:
6,476

Related videos on Youtube

equaeghe
Author by

equaeghe

Updated on September 18, 2022

Comments

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

    • Jpark822
      Jpark822 almost 11 years
      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).
    • equaeghe
      equaeghe almost 11 years
      @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
    equaeghe almost 11 years
    Ah, would \:;s=sed;command -v gsed >/dev/null && s=gsed; exec "$s" -f "$0" "$@";$:s/^// then be more portable?
  • equaeghe
    equaeghe almost 11 years
    Would \:;`command -v gsed || command -v sed` -f "$0" "$@";$:s/^// be a portable alternative?
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    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 (!?).
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    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.