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

iga*_*gal 10 awk shell-script portability

我正在使用一个命令行应用程序,它本质上是一个 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
Run Code Online (Sandbox Code Playgroud)

另一种变化可能是:

awk -Wversion &>/dev/null && echo gawk || echo nawk
Run Code Online (Sandbox Code Playgroud)

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

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

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

gle*_*man 9

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
Run Code Online (Sandbox Code Playgroud)

或者,测试是 awk 是一个符号链接:

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


Arc*_*mar -1

肮脏的黑客

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
Run Code Online (Sandbox Code Playgroud)
  • nawk-only-function() 存在于nawk