因此,GNU awk 具有 macOS awk 中缺少的一些扩展。
我想确保我的 awk 程序也可以在 macOS awk(我无权访问)上运行。
现在 GNU awk 有两个不同的兼容性标志,我不确定使用哪个:--traditional
和--posix
。
后者更为严格。是否--traditional
足以实现与 macOS awk 的兼容性?
答案1
没有为什么
- MacOS 实现了属于 POSIX 一部分但不属于 BWK awk(旨在
gawk --traditional
兼容)的功能,例如 RE 间隔,因此某些语言结构在两种变体中的含义并不相同,尽管在这两种变体中都有效。 - MacOS awk 具有 GNU awk 中不存在的错误,因此无论您提供什么选项,工作的 gawk 脚本都可能在 MacOS 上失败。
- 两个 awk 都可以/确实实现 POSIX 或“传统”awk 规范未定义的功能,无论它们喜欢什么。
因此,它--posix
会更接近您想要的,--traditional
但与 MacOS 仍然存在差异,并且选项和任何其他选项都不会满足您的要求 - 保证 gawk 脚本将在 MacOS awk 中运行相同的内容。
例如,使用 gawk(它不像
{2}
传统模式那样支持 RE 间隔,但在 posix 模式下支持):$ awk --version | head -1 GNU Awk 5.0.1, API: 2.0 $ echo 'ab{2}c' | awk --traditional '/b{2}/' ab{2}c $ echo 'ab{2}c' | awk --posix '/b{2}/' $ $ echo 'ab{2}c' | awk --traditional '/b\{2\}/' awk: cmd. line:1: warning: regexp escape sequence `\{' is not a known regexp operator awk: cmd. line:1: warning: regexp escape sequence `\}' is not a known regexp operator ab{2}c
而 MacOS 确实支持 RE 间隔:
$ awk --version | head -1 awk version 20200816 $ echo 'ab{2}c' | awk '/b{2}/' $ $ echo 'ab{2}c' | awk '/b\{2\}/' ab{2}c
例如,使用 gawk:
$ awk 'BEGIN{print 1 == 2 ? 3 : 4}' 4 $ awk --traditional 'BEGIN{print 1 == 2 ? 3 : 4}' 4 $ awk --posix 'BEGIN{print 1 == 2 ? 3 : 4}' 4
而对于 MacOS:
$ awk 'BEGIN{print 1 == 2 ? 3 : 4}' awk: syntax error at source line 1 context is BEGIN{print 1 >>> == <<< awk: illegal statement at source line 1 awk: illegal statement at source line 1
看https://unix.stackexchange.com/a/588743/133219有关该特定错误的更多信息。
将目录作为文件名处理的另一个区别是:
$ mkdir foo $ echo 7 > bar
使用 GNU awk:
$ awk '{print FILENAME, $0}' foo bar awk: warning: command line argument `foo' is a directory: skipped bar 7 $ awk --traditional '{print FILENAME, $0}' foo bar awk: fatal: cannot open file `foo' for reading (Is a directory) $ awk --posix '{print FILENAME, $0}' foo bar awk: fatal: cannot open file `foo' for reading (Is a directory)
和 MacOS awk:
$ awk '{print FILENAME, $0}' foo bar bar 7