如何在 Ubuntu 上测试 nawk?

如何在 Ubuntu 上测试 nawk?

我正在编写一个需要在 Apple MacO 和 Ubuntu 之间移植的脚本。前者的“awk”是(我相信)由nawk提供,而后者是gawk提供的。实现之间存在显着差异。

具体来说,我正在 Ubuntu 22.04LTS 上进行开发,不幸的是......

# apt install nawk
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package nawk

(在 Debian Bullseye 上也是如此)

我还尝试下载 nawk 源代码并进行编译,但是 yacc 在我的发行版上不可用,并且 Bison 的兼容性不足以运行 makefile。

有没有办法让gawk表现像诺克?

如果做不到这一点,是否有一个 Linux 发行版可以从存储库中获得 nawk?

答案1

nawk是的,其存储库中至少有一个发行版。我确信有很多,但我是通过我的 Arch 系统写这篇文章的,我可以确认 Arch 具有nawk

$ pacman -Ss nawk
community/nawk 20220912-1 [installed]
    The one, true implementation of AWK

也就是说,这里一个有用的技巧是使用 busybox awk忙碌盒是一个很棒的工具,非常有用并且常见于嵌入式系统,它提供了各种标准工具的精简版本:

BusyBox 将许多常见 UNIX 实用程序的微型版本组合到一个小型可执行文件中。它提供了您通常在 GNU fileutils、shellutils 等中找到的大多数实用程序的替代品。BusyBox 中的实用程序通常比其全功能的 GNU 同类程序具有更少的选项;然而,其中包含的选项提供了预期的功能,并且行为与 GNU 对应选项非常相似。 BusyBox 为任何小型或嵌入式系统提供了相当完整的环境。

它提供的工具之一是awk,因此如果您安装busybox在 Ubuntu ( sudo apt install busybox) 中,则可以运行busybox awk以获得最小的awk.这是不是 nawk,但它是一个简单、精简的版本awk,它应该提供比gawk.如果您的脚本适用于 busybox awk,那么它很可能也适用于gawknawk。这不是一个完美的解决方案,我确实找到了一条评论该网站上的另一个答案声称“实际上,BusyBox 的awk行为与gawkv3 非常接近;我认为它的功能比nawk,但这只是一个开始。

最后,也许是最相关的,gawk实际上有一个--posix选项:

-P

--posix

在严格的 POSIX 模式下运行。这将禁用所有 gawk 扩展(就像 --traditional 一样)并禁用 POSIX 不允许的所有扩展。看常用扩展总结有关 gawk 中被此选项禁用的扩展的摘要。此外,还适用以下附加限制:

'?' 之后不允许换行或“:”(参见条件表达式)。在命令行上指定“-Ft”不会将 FS 的值设置为单个制表符(请参阅指定字段的分隔方式)。语言环境的小数点字符用于解析输入数据(请参阅你所在的位置会有所不同)。

如果您在命令行上同时提供 --traditional 和 --posix,则 --posix 优先。如果提供了两个选项,gawk 会发出警告。

因此,最好的选择是gawk --posix在测试时使用,以确保只使用便携式功能。


或者,也可能不是。埃德·莫顿我们的一位常驻 awk 专家在一条现已删除的评论中这样说道:

gawk --posix并不能确保您只使用便携式功能。例如,使用该选项集split("foo",arr,"")将填充arr[]字符串中的每个字符"foo",但其他 awks 可以填充arr[]整个字符串的单个条目"foo"或执行其他任何操作并符合 POSIX,因为使用空字符串作为分隔符的字段拆分是未定义的行为。所做--posix的就是关闭 gawk 扩展,但您仍然需要手动注意编写依赖于 POSIX 未定义的任何行为的 gawk 实现的代码。 ——埃德·莫顿

Ed 对 awk 的了解比我多得多,所以我相信他的话。

答案2

经过更多搜索后,我找到了更新版本的 nawk (或者至少我相信这是nawk),路标来自https://www.cs.princeton.edu/~bwk/btl.mirror/index.htmlhttps://github.com/onetrueawk/awk

不过我仍然有兴趣看看是否有人有更好的建议。

答案3

这类问题的答案是你需要一个跨平台的项目。

您应该能够在必须运行的平台上检查您的项目,运行所需的任何准备工作,然后执行测试用例套件。

每当您发布脚本的新版本时,您都必须执行该测试计划:在所有受支持的平台上更新到发布基线,运行测试用例,并执行您拥有的任何其他测试计划,以获得事情正常运行的信心每个支持的平台。

只要小心一点,您应该能够编写在 GNU Awk、nawk 等中产生相同结果的 Awk 代码。

nawk 源代码并进行编译,但是 yacc 在我的发行版上不可用,并且 Bison 不够兼容

我发现“One True Awk”项目做了一些非常愚蠢的事情。定义.makefileYACC = bison -d这意味着awkgram.y语法文件现在受到用户安装的任何 Bison 版本的默认行为的影响。使问题更加复杂的是,该项目没有提供维护者实际构建和测试的生成的解析器源。因此,下游用户为程序的相当重要的部分运行不同的 C 代码。

如果您在安装 Bison 时遇到困难,请尝试将其更改为bison --yacc -d. 没有or参数bison就不是真正的 Yacc 。-y--yacc

如果失败,请在其他平台上生成解析器,并使用这些生成的文件。

即使您让 nawk 在平台 A 上运行,也不意味着您可以假设您的代码无需测试即可在平台 B 上运行。

无论如何,它看起来像一个真正的 awk源代码不包含 Yacc 生成的解析器,这是一个错误。您可以做的就是在适用的平台上运行 Yacc,然后将结果y.tab.cy.tab.h文件添加到本地树中。确保您触摸了时间戳,以便这些文件比这些文件更新,awkgram.y这样makefile就不会尝试重建它们;或者调整makefile.

Yacc 程序生成可移植的 C 输出,以便下游用户无需安装 Yacc 即可构建该程序。使用 Yacc 语法的项目应该始终发布生成的代码,以便下游的每个人都编译相同的 C。当人们拥有相同的 C 源代码,但为不同的机器和环境构建它们时,这已经足够危险了。

我很惊讶 Bison 无法处理awkgram.yBrian Kernighan 的 awk 中的文件。你必须使用bison --yaccbison -y。在 Bison 提供 Yacc 实现的系统上,通常有一个名为 的脚本yacc将其参数传递给bison -ybison --yacc。我刚刚检查了https://github.com/onetrueawk/awk.git一个 Ubuntu 18 实例,其中默认安装了 Bison 3.0.4,以及/usr/local/bin.两人都awkgram.y无误地接受。

相关内容