Shell – How to programmatically detect awk flavor (e.g. gawk vs nawk)

awkportabilityshell-script

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.

Best Answer

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

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

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

Alternatively, test is awk is a symbolic link:

awk=$( command -v awk )
[[ -L $awk ]] && readlink $awk # make some decision about the result of that
Related Question