4

So, GNU awk has some extensions that are missing in the macOS awk.

I want to be sure that my awk program also runs on the macOS awk (which I don't have access to).

Now GNU awk has two different compatibility flags and I'm not sure which to use: --traditional and --posix.

The latter is more strict. Does --traditional suffice to achieve compatibility with the macOS awk?

1
  • 1
    When in doubt, go with POSIX. It will work well on BSD styled kernels such as XNU (MacOS).
    – Cbhihe
    Apr 21 at 20:39

1 Answer 1

7

No because

  1. MacOS implements features that are part of POSIX but weren't part of BWK awk (which gawk --traditional is intended to be compatible with) such as RE intervals so some language constructs don't mean the same across the 2 variants despite being valid in both.
  2. MacOS awk has bugs that aren't present in GNU awk so a working gawk script could fail on MacOS no matter what options you give it.
  3. Both awks can/do implement functionality that's undefined by POSIX or the "traditional" awk spec however they like.

So --posix will be closer to what you want than --traditional but still has differences with MacOS, and neither option nor any other option does what you want - guarantee a gawk script will run the same in MacOS awk.

  1. For example, with gawk (which does not support RE intervals like {2} in traditional mode but does in posix mode):

    $ 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
    

    whereas with MacOS which does support RE intervals:

    $ awk --version | head -1
    awk version 20200816
    
    $ echo 'ab{2}c' | awk '/b{2}/'
    $
    
    $ echo 'ab{2}c' | awk '/b\{2\}/'
    ab{2}c
    
  2. For example, with 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
    

    whereas with 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
    

    See https://unix.stackexchange.com/a/588743/133219 for more info on that specific error.

  3. Another difference in how handling a directory as a file name is handled:

    $ mkdir foo
    $ echo 7 > bar
    

    with 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)
    

    and MacOS awk:

    $ awk '{print FILENAME, $0}' foo bar
    bar 7
    
2
  • --posix would be closer for busybox awk also?
    – thanasisp
    Apr 27 at 21:09
  • 1
    @thanasisp I've never used busybox awk myself but I just found a comment about busybox in the gawk manual (gnu.org/software/gawk/manual/html_node/Other-Versions.html) that says It includes a full implementation of POSIX awk so in that case, yes --posix would be the right flag.
    – Ed Morton
    Apr 27 at 21:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.