I'm using a command-line application which is essentially a collection of bash shell scripts. The application was written to run on BSD/OSX and also on Linux. One of the scripts relies on awk. It contains two awk commands: one written for nawk (the standard BSD awk implementation) and one written for gawk (the GNU awk implementation).

The two awk commands in question are not cross-compatible with the different environments; in particular the nawk command fails when run with gawk. The script checks the kernel name (i.e. uname -s) in order to determine the host environment, and then runs the appropriate awk command. However I prefer to work on Mac OS X with the GNU core utilities installed, so the script fails to run correctly.

In the process of thinking about how best to fix this bug it occurred to me that it would be nice to know how to programmatically distinguish between different flavors of the common command-line utilities, preferably in a relatively robust and portable way.

I noticed that nawk doesn't accept the '-V' flag to print the version information, so I figured that something like the following should work:

awk -V &>/dev/null && echo gawk || echo nawk

Another variation could be:

awk -Wversion &>/dev/null && echo gawk || echo nawk

This seems to work on my two testing environments (OS X and CentOS). Here are my questions:

  • Is this the best way to go?
  • Is there a way to extend this to handle other variations of awk (e.g. mawk, jawk, etc.)?
  • Is it even worth worrying about other versions of awk?

I should also mention that I know very little about awk.

  • If the awk command isn't extremely complicated, or even if it is, you might consider porting it to perl or something else which is uniform.
    – Wildcard
    Oct 16, 2015 at 13:30
  • Let see awk version by awk -Wv instead of host environment
    – Costas
    Oct 16, 2015 at 13:35
  • 1
    My awk is very weak but I believe that it is quite simple. I actually already rewrote it in pure bash. But this is one of those situations where I'm more interested in satisfying my curiosity than in actually solving the original problem.
    – igal
    Oct 16, 2015 at 13:37
  • @Costas Something like that actually did occur to me, but I wasn't sure how fragile it might be; I know very little about awk. I've added my current solution to my post.
    – igal
    Oct 16, 2015 at 13:49
  • 1
    One alternative is to ignore what version of awk is being used, and code to the POSIX specification instead.
    – chepner
    Oct 16, 2015 at 18:23

5 Answers 5

if awk --version 2>&1 | grep -q "GNU Awk"
    awk 'BEGIN {print "I am GNU Awk"}'

elif awk -Wv 2>&1 | grep -q "mawk"
    awk 'BEGIN {print "I am mawk"}'

    awk 'BEGIN {print "I might be nawk, might not be"}'

Alternatively, test is awk is a symbolic link:

awk=$( command -v awk )
[[ -L $awk ]] && readlink $awk # make some decision about the result of that
  • This one is okay... but there are a few variations (hard to distinguish) for old-awk, nawk, and the newer BWK versions. For those, a sample script might be be tailored. Oct 18, 2015 at 17:45

Try using the which command and use its exit code.

which nawk
if [[ $? == 0 ]]; then

then format your script to use the variable as the command

$command '{print $1}` 

would be read as

nawk '{print $1}`

if which finds nawk. Otherwise it would use gawk

  • 1
    since command is a bash builtin you might want to use a different name for your variable, and you might also want to see the incredibly detailed answer about why for many shells there are better alternatives to which at unix.stackexchange.com/a/85250/109842 Oct 16, 2015 at 14:33

A dirty hack

if nawk 'BEGIN { nawk-only-function() ;}' 
   nawk -f nfile.awk ...
   gawk -f gfile.awk ...
  • where nawk-only-function() exist only on nawk

GNU Awk is often installed as gawk, with awk as a symlink to it on systems where GNU is the default. I would guess this is the case on BSD and OS X systems, since they already have their own awk.

if gawk '{ exit; }' < /dev/null 2> /dev/null
    echo "gawk available"
    echo "gawk not available"
  • Thank you for your input. This is a good idea and you're correct that this is the case for me on OS X. But I was hoping for an intrinsic solution, so to speak.
    – igal
    Oct 16, 2015 at 14:16
  • This is very innacurate, as there are many more versions of awk than just "mawk / gawk" (regular awk, for exemple, is neither) Sep 21, 2020 at 17:22

I'd probably try abusing the AC_PROG_AWK m4 macro in autoconf to choose one, ordering them appropriately. It's probably overkill though

  • Could you edit to provide a bit more detail on how you'd use that macro for this scenario? Oct 17, 2015 at 0:33
  • It doesn't actually tell which one it found, but simply looks for awk implementations and chooses one based on its name. Oct 18, 2015 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.