我正在编写一个脚本,需要在Apple、MacOs和Ubuntu之间移植。前者的'awk‘(我相信)是由nawk提供的,而后者则是gawk。实现之间有很大的差异。
具体来说,我正在Ubuntu22.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。
有办法让呆子表现得像纳克吗?
如果做不到这一点,是否有一个Linux发行版可以从回购中获得nawk?
发布于 2023-05-16 16:25:59
经过更多的搜索,我发现了https://www.cs.princeton.edu/~bwk/btl.mirror/index.html at https://github.com/onetrueawk/awk上发布的nawk的最新版本(或者至少我认为是nawk)。
不过,我还是想看看是否有人有更好的建议。
发布于 2023-05-16 17:27:38
是的,至少有一个发行版在其存储库中有nawk。我确信有很多,但我是从我的Arch系统中编写的,我可以确认Arch有nawk:
$ pacman -Ss nawk
community/nawk 20220912-1 [installed]
The one, true implementation of AWK尽管如此,这里一个有用的技巧是使用busybox awk来代替。百事箱是一个很好的工具,非常有用,在嵌入式系统中也很常见,它提供了各种标准工具的精简版本:
BusyBox将许多常见的UNIX实用程序的微小版本组合成一个小的可执行文件。它为您通常在GNU、their等中找到的大多数实用程序提供了替换。BusyBox中的实用程序通常比它们的功能齐全的GNU堂兄弟拥有更少的选项;但是,包含的选项提供了预期的功能,其行为非常类似于它们的GNU对应程序。BusyBox为任何小型或嵌入式系统提供了相当完整的环境。
它提供的工具之一是awk,所以如果您在Ubuntu (sudo apt install busybox)中安装了busybox,那么您就可以运行busybox awk来获得一个最小的awk。这不是nawk,但它是一个简单、精简的awk版本,它应该提供一个比gawk更可移植的工具集。如果您的脚本适用于busybox awk,那么它很可能也适用于gawk和nawk。这不是一个完美的解决方案,我在这个网站上的另一个回答中找到了评论,它声称“实际上,BusyBox awk在行为上非常接近gawk v3;我认为它比nawk功能更全面,但这是一个开始。”
最后,也许最重要的一点是,gawk实际上有一个--posix选项:
-P --posix在严格的POSIX模式下工作.这将禁用所有gawk扩展(与传统扩展一样),并禁用所有POSIX不允许的扩展。有关gawk中被此选项禁用的扩展的摘要,请参见通用扩展摘要。此外,还适用以下附加限制:在“?”之后不允许使用Newline。或“:”(见条件表达式)。在命令行上指定‘-Ft’并不会将FS的值设置为单个TAB字符(参见指定字段如何分隔)。区域设置的小数点字符用于解析输入数据(请参阅你所处的位置会让你与众不同)。如果在命令行中同时提供传统的posix和-posix,那么-posix优先。如果提供了这两个选项,gawk就会发出警告。
因此,您最好的选择是在测试时使用gawk --posix,以确保您只使用可移植特性。
或者也许不是。我们的常驻awk专家之一埃德·莫顿在一条现已删除的评论中这样说:
gawk --posix并不能确保您只使用可移植特性。例如,使用该选项集,split("foo",arr,"")将使用字符串"foo"中的每个字符填充arr[],但其他awk可以使用单个条目填充arr[],即整个字符串"foo",也可以执行任何其他操作,并且符合POSIX,因为使用空字符串作为分隔符的字段拆分是未定义的行为。--posix所做的是关闭gawk扩展,但是您仍然需要手动知道编写依赖于POSIX未定义的几种行为中的gawk实现的代码。-埃德·莫顿
艾德对awk的了解远远超过我,所以我会相信他的话。
发布于 2023-05-19 22:17:26
这种问题的答案是,你需要一个跨平台的项目。
您应该能够在那些必须工作的平台上检查项目,运行所需的任何准备,然后执行测试用例套件。
无论何时发布新版本的脚本,都必须执行该测试计划:在所有受支持的平台上更新发布基线,并运行测试用例,并执行其他测试计划,以获得在每个受支持平台上工作的信心。
小心点,您应该能够编写在GNU Awk、nawk和其他方面产生相同结果的Awk代码。
nawk源代码和编译,但是yacc在我的发行版上是不可用的,而Bison是不够兼容的。
我看到,“一个真正的Awk”项目做了一些非常愚蠢的事情。makefile定义了YACC = bison -d。这意味着awkgram.y语法文件现在取决于用户安装的任何版本Bison的默认行为。为了使问题更加复杂,该项目不提供维护人员实际构建和测试的生成的解析器源。因此,下游用户正在为程序的一个非常重要的部分运行不同的C代码。
如果您的Bison安装有困难,请尝试将其更改为bison --yacc -d。bison实际上并不是没有-y或--yacc参数的Yacc。
否则,在其他平台上生成解析器,并使用这些生成的文件。
即使您在平台A上运行nawk,这也不意味着您可以假设您的代码可以在平台B上运行而无需测试。
无论如何,看起来一辆真Awk源代码不包括Yacc生成的解析器,这是一个错误。您可以做的就是在一个平台上运行Yacc,然后将生成的y.tab.c和y.tab.h文件添加到本地树中。确保您触摸了时间戳,以便这些文件比awkgram.y更新,这样makefile就不会尝试重新构建它们;否则就会调整makefile。
Yacc程序生成可移植C的输出,以便下游用户可以在不安装Yacc的情况下构建程序。使用Yacc语法的项目应该始终发布生成的代码,这样每个人都在下游编译相同的C。如果人们有相同的C源,但是为不同的机器和环境构建C源,这已经够危险的了。
我很惊讶Bison无法在Brian的awk中处理awkgram.y文件。您必须使用bison --yacc或bison -y。在由Bison提供Yacc实现的系统中,通常有一个名为yacc的脚本将其参数传递给bison -y或bison --yacc。我刚刚在一个Ubuntu18实例上签出了https://github.com/onetrueawk/awk.git,其中我有默认的Bison3.0.4安装,以及/usr/local/bin中的Bison2.5。他们都接受awkgram.y,没有错误。
https://unix.stackexchange.com/questions/746072
复制相似问题