Combine o intervalo de colunas com a mesma chave

1
Input file tab separated:
A   |B   |  C | KEY  |  D|  E|  F  |G     | H | I | J   |   k |      
----|----|----|------|---|---|-----|------|---|---|-----|-----|      
word|word|word| one  |  8|  8|qw123| ""   | ""| ""| word| word|      
word|word|word| one  |  8|  8|qw234| ""   | ""| ""| word| word|      
word|word|word| one  |  8|  8|qw111| er432| ""| ""| word| word|      
word|word|word| seven|  8|  8|tr123| ""   | ""| ""| word| word|      
word|word|word| seven|  8|  8|ww000| ""   | ""| ""| word| word|      


Desired Output:                                                                     
A   |B   |  C | KEY  |D |E |F    |G    |H    |I    |J   |K   |  
----|----|----|------|--|--|-----|-----|-----|-----|----|----|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|one   | 8| 8|qw123|qw234|qw111|er432|word|word|
word|word|word|seven | 8| 8|tr123|ww000|""   |""   |word|word|
word|word|word|seven | 8| 8|tr123|ww000|""   |""   |word|word|

Trata-se de mesclar o intervalo de colunas [F para I] com a mesma KEY. É possível conseguir isso sem usar arrays no AWK? Como posso controlar quando o valor da coluna-chave muda?

    
por Polucho 10.11.2015 / 17:47

1 resposta

1

Eu não vejo como você poderia fazer isso no Awk sem usar arrays. Seria mais conveniente em Gawk, o que permite que elementos de array sejam arrays, mas é bastante fácil de fazer com arrays multidimensionais simulados do Awk comuns.

Basicamente, precisamos nos lembrar das linhas de entrada e então produzi-las (com os campos F-I atualizados) quando a chave é alterada. Também precisamos fazer isso no final do arquivo. Por conveniência, usamos uma função de saída, pois ela será inevitavelmente chamada de dois lugares.

O seguinte usa números de coluna fixos: 1-6 e 11-12 para os campos de dados padrão, com 4 sendo o campo-chave e 7-10 para os campos mesclados, que eu chamei de tags por falta de um nome melhor. Isso não é ótimo estilo, e provavelmente deve ser fatorado em algumas variáveis.

awk -F '\t' '
  function show_and_reset(            i, c) {
    for (i = 1; i <= count; ++i) {
      for (c = 1; c <= 6; ++c) printf "%s\t", data[i,c]
      for (f in tags) printf "%s\t", f;
      for (c = ntags; c <= 3; ++c) printf "\t" 
      for (c = 11; c <= 12; ++c) printf "\t%s", data[i,c]
      print ""
    }
    /* Clear the holding data */
    for (f in tags) delete tags[f]
    ntags = 0;
    count = 0
  }
  /* Record one line of data */
  function record(                   c) {
    ++count;
    for (c = 1; c <= 6; ++c) data[count,c] = $c
    for (c = 11; c <= 12; ++c) data[count,c] = $c
    for (c = 6; c <= 10; ++c) 
      if ($c != "" && !tags[$c]++) ++ntags;
  }
  $4 != key { show_and_reset(); key = $4; }
            { record(); }
  END       { show_and_reset(); }
'
    
por 10.11.2015 / 21:35

Tags