Awk

GNU awk –traditional vs –posix

  • April 22, 2022

因此,GNU awk 有一些 macOS awk 中缺少的擴展。

我想確保我的 awk 程序也可以在 macOS awk(我無權訪問)上執行。

現在 GNU awk 有兩個不同的兼容性標誌,我不確定使用哪個:--traditional--posix.

後者更為嚴格。是否--traditional足以實現與 macOS awk 的兼容性?

沒有為什麼

  1. MacOS 實現的功能是 POSIX 的一部分,但不是 BWK awk 的一部分(gawk --traditional旨在與之兼容),例如 RE 間隔,因此某些語言結構在 2 個變體中並不意味著相同,儘管在兩者中都有效。
  2. MacOS awk 具有 GNU awk 中不存在的錯誤,因此無論您提供什麼選項,在 MacOS 上工作的 gawk 腳本都可能失敗。
  3. 兩個 awk 都可以/確實實現 POSIX 或“傳統”awk 規範未定義的功能,但他們喜歡。

所以--posix將比你想要的更接近,--traditional但與 MacOS 仍然存在差異,並且任何選項或任何其他選項都不符合你的要求 - 保證 gawk 腳本將在 MacOS awk 中執行相同。

  1. 例如,使用 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

而對於支持 RE 間隔的 MacOS:

$ awk --version | head -1
awk version 20200816

$ echo 'ab{2}c' | awk '/b{2}/'
$

$ echo 'ab{2}c' | awk '/b\{2\}/'
ab{2}c
  1. 例如,使用 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。 3. 將目錄作為文件名處理的另一個區別是:

$ 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

引用自:https://unix.stackexchange.com/questions/699842