problema comum de buffer awk ao chamar comandos shell

2

Algumas precisões:

  • awk normal, NÃO gawk
  • AIX 6.1 e shell antigo: GNU bash, versão 2.05b.0 (1)

Eu estou tentando mostrar algumas coisas na ordem correta, então eu faço saídas de pipe através do "tipo" e "uniq" do shell ... Mas não consigo obter a saída na ordem em que escrevo.

Código de problema:

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

Produz:

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

?? ... estou com uma perda: parece que se eu adicionar: system (""); antes das linhas para exibir os servidores, isso não ajuda ...

Alguns testes relevantes no mesmo sistema:

1) semelhante ao meu script: saída "longa" através de chamadas do sistema, fica ilegível:

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) MESMOS, mas desta vez adicionamos um final '| cat ': magicamente reordena a saída .... mas isso não ajuda se eu fizer o mesmo no meu script acima ...

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!
    
por Olivier Dulac 14.09.2016 / 17:51

1 resposta

3

Você precisa fechar o tubo dentro do awk para liberá-lo. Para o seu segundo exemplo, faça:

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

Para torná-lo mais evidente em seu primeiro exemplo, faça

cmd = "grep . | sort | uniq | xargs echo ";
printf groupe "\n" | cmd;
close(cmd);
    
por 14.09.2016 / 20:00