如何以编程方式检测 awk 风格(例如 gawk 与 nawk)

如何以编程方式检测 awk 风格(例如 gawk 与 nawk)

我使用的命令行应用程序本质上是 bash shell 脚本的集合。该应用程序被编写为可以在 BSD/OSX 和 Linux 上运行。其中一个脚本依赖于 awk。它包含两个 awk 命令:一个为 nawk(标准 BSD awk 实现)编写,另一个为 gawk(GNU awk 实现)编写。

所讨论的两个 awk 命令与不同环境不交叉兼容;特别是当使用 gawk 运行时 nawk 命令会失败。该脚本检查内核名称(即uname -s)以确定主机环境,然后运行适当的 awk 命令。不过,我更喜欢在安装了 GNU 核心实用程序的 Mac OS X 上工作,因此脚本无法正确运行。

在思考如何最好地修复这个错误的过程中,我突然想到,如果能够以编程方式区分常见命令行实用程序的不同风格,最好是以相对健壮和可移植的方式来区分,那就太好了。

我注意到 nawk 不接受“-V”标志来打印版本信息,所以我认为类似以下的内容应该有效:

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

另一种变化可能是:

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

这似乎适用于我的两个测试环境(OS X 和 CentOS)。这是我的问题:

  • 这是最好的方法吗?
  • 有没有办法扩展它来处理 awk 的其他变体(例如 mawk、jawk 等)?
  • 是否值得担心其他版本的 awk?

我还应该提到我对 awk 知之甚少。

答案1

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

或者,test is awk 是一个符号链接:

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

答案2

尝试使用该which命令并使用其退出代码。

which nawk
if [[ $? == 0 ]]; then
    command="nawk"
else
    command="gawk"
fi

然后格式化脚本以使用变量作为命令

$command '{print $1}` 

将被读作

nawk '{print $1}`

如果which找到nawk。否则它会使用gawk

答案3

GNU Awk 通常安装为gawk,并awk在默认使用 GNU 的系统上作为其符号链接。我猜想 BSD 和 OS X 系统就是这种情况,因为它们已经有自己的awk.

if gawk '{ exit; }' < /dev/null 2> /dev/null
then
    echo "gawk available"
else
    echo "gawk not available"
fi

答案4

我可能会尝试滥用 autoconf 中的 AC_PROG_AWK m4 宏来选择一个,并对它们进行适当的排序。但这可能有点过分了

相关内容