GNU awk --traditional 및 --posix

GNU awk --traditional 및 --posix

따라서 GNU awk에는 macOS awk에 없는 일부 확장 기능이 있습니다.

내 awk 프로그램이 macOS awk(액세스 권한이 없음)에서도 실행되는지 확인하고 싶습니다.

이제 GNU awk에는 두 가지 다른 호환성 플래그가 있는데 어느 것을 사용해야 할지 모르겠습니다: --traditional--posix.

후자가 더 엄격합니다. --traditionalmacOS awk와의 호환성을 달성하는 것으로 충분 합니까 ?

답변1

이유없이

  1. MacOS는 gawk --traditionalRE 간격과 같이 POSIX의 일부이지만 BWK awk(호환 예정)가 아닌 기능을 구현하므로 일부 언어 구성은 두 변형 모두에서 유효하지만 두 변형에서 동일한 의미를 갖지 않습니다.
  2. MacOS awk에는 GNU awk에 없는 버그가 있으므로 어떤 옵션을 제공하든 MacOS에서 gawk 스크립트 작업이 실패할 수 있습니다.
  3. 두 awk 모두 POSIX 또는 "전통적인" awk 사양에 의해 정의되지 않은 기능을 원하는대로 구현할 수 있습니다.

따라서 --posix원하는 것에 더 가깝지만 --traditional여전히 MacOS와 차이가 있으며 옵션이나 다른 옵션 모두 원하는 대로 작동하지 않습니다. gawk 스크립트가 MacOS awk에서 동일한 작업을 실행한다는 것이 보장됩니다.

  1. 예를 들어, gawk 사용(레거시 모드와 같은 RE 간격을 지원하지 않지만 {2}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
    
  2. 예를 들어 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
    

관련 정보