쉘 명령 호출 시 일반적인 awk 버퍼링 문제

쉘 명령 호출 시 일반적인 awk 버퍼링 문제

약간의 정밀도:

  • gawk가 아닌 일반 awk
  • AIX 6.1 및 이전 쉘: GNU bash, 버전 2.05b.0(1)

올바른 순서로 무언가를 표시하려고 하므로 쉘의 "sort" 및 "uniq"를 통해 출력을 파이프하지만...작성한 순서대로 출력을 얻을 수 없습니다.

문제가 있는 코드:

egrep -i "something_FREQUENT" BIGFILE | sort | awk -F',' '
      { servs=servs $1 " " ; groupe=groupe "\n   " $2 ; }
  END { print "Groupes (alphabetical order):" ;
        printf groupe "\n" | "grep . | sort | uniq | xargs echo ";
        print ; rem="extra newline to help buffering... does NOT help.";
        system(""); rem="supposed to force flush of stdout... does NOT help.";
        print "Servers:"
        printf "%s\n", servs;
      } ' # if I add a final: "| cat" here (after "'"), does NOT help?... see last example

다음과 같이 출력됩니다.

Groupes (alphabetical order):

Servers:
( here a quite long list of severs... maybe until "buffer size" length? )
( etc.... but at some point :)(HERE_THE_groupe_OUTPUT)(rest of the servers here....)

??...어리둥절합니다. 서버를 표시하는 줄 앞에 system("");을 추가해도 도움이 되지 않는 것 같습니다...

동일한 시스템에 대한 일부 관련 테스트:

1) 내 스크립트와 유사합니다. 시스템 호출을 통한 "긴" 출력이 깨졌습니다.

prompt$:  yes "test1" | head -10 | awk '
         { all=all "\n" $0; }
     END { print "first line:"  ;
           printf all "\n" | "sort "; 
           system(""); 
           print "last line" ;
         }'

first line:
last line

test1
test1
test1
test1
test1
test1
test1
test1
test1
test1
  # notice: the order is mixed: the shell command output is last.

2) 동일하지만 이번에는 마지막 '| cat'을 추가합니다. 마술처럼 출력 순서가 변경됩니다. 하지만 위 스크립트에서 동일한 작업을 수행하면 도움이 되지 않습니다....

prompt$:  yes "test2" | head -10 | awk '
         { all=all "\n" $0; }
     END { print "first line:"  ;
           printf all "\n" | "sort "; 
           system(""); 
           print "last line" ;
         }' | cat  # ONLY ADDITION: pipe awk through cat... this HELPS here (but NOT in my script!... ??)

first line:

test2
test2
test2
test2
test2
test2
test2
test2
test2
test2
last line
  # notice: the order is OK!

답변1

파이프를 플러시하려면 awk 내에서 파이프를 닫아야 합니다. 두 번째 예에서는 다음을 수행합니다.

yes "test1" | head -10 | awk '
    { all=all "\n" $0; }
END { print "first line:"  ;
      printf all "\n" | "sort "; 
      close("sort ");
      print "last line" ;
    }'

첫 번째 예에서 더 명확하게 하려면 다음을 수행하십시오.

cmd = "grep . | sort | uniq | xargs echo ";
printf groupe "\n" | cmd;
close(cmd);

관련 정보