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


8

我使用的命令行应用程序实质上是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的其他变体(例如,awkk,jawk等)?
  • 甚至值得担心其他版本的awk吗?

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


如果awk命令不是很复杂,即使不是那么复杂,您也可以考虑将其移植到perl或其他统一的东西中。
— 2015年

让我们通过awk -Wv主机环境而不是主机环境查看awk版本
— Costas 2015年

1
我的awk很弱,但是我相信这很简单。我实际上已经用纯重的方式重写了它。但是,在这种情况下,我对满足好奇心比真正解决原始问题更感兴趣。
— igal 2015年

@Costas实际上确实发生了这样的事情,但是我不确定它可能有多脆弱。我对awk知之甚少。我已将当前的解决方案添加到我的帖子中。
— igal 2015年

1
一种选择是忽略awk使用的是哪个版本,而代之以POSIX规范的代码。
— chepner

Answers:


7
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

这个还可以...但是旧的awk,nawk和较新的BWK版本有一些变体(很难区分)。对于那些,可能会定制示例脚本。
— Thomas Dickey

3

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

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

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

$command '{print $1}` 

将被读取为

nawk '{print $1}`

如果which发现nawk。否则它将使用gawk


1
因为command是bash内置的,所以您可能想为变量使用其他名称,并且您可能还希望which在unix.stackexchange.com/a/85250/109842
— 埃里克·雷诺夫

1

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

谢谢您的意见。这是个好主意,您是正确的,在OS X上我就是这种情况。但是,我一直希望有一个内在的解决方案。
— igal 2015年

0

肮脏的骇客

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
  • 其中,nawk-only-function() 仅上存在nawk

-2

我可能会尝试滥用autoconf中的AC_PROG_AWK m4宏来选择一个宏,并对其进行适当排序。虽然这可能是过分的


您能否编辑以提供更多有关如何在此情况下使用该宏的详细信息?
— Michael Homer 2015年

它实际上并不会告诉您找到了哪个,而只是寻找awk实现并根据其名称选择一个。
— Thomas Dickey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.