Mesclar valores de linhas consecutivas se eles tiverem os mesmos valores em uma coluna diferente (AWK)

2

Eu preciso combinar o primeiro valor ( $1 ) de linhas consecutivas se o quarto valor ( $4 ) for o mesmo ( I-PER ).

Consegui filtrar os valores de que preciso simplesmente usando o awk:

awk ' ($4 == "I-PER") {printf $1; printf "\n" }

Também descobri como mesclar linhas com valores de coluna duplicados, mas não valores consecutivos.

Exemplo (entrada):

Comandante  comandante  NP00000 I-PER
de  de  SPS00   I-PER
la  el  DA0FS0  I-PER
Guardia guardia NP00000 I-PER
Civil   civil   NP00000 I-PER
Pamplona    pamplona    NP00000 I-LOC
Poblador    poblador    NP00000 I-PER

Exemplo (saída):

Comandante de la Guardia Civil
Poblador
    
por Mikel SS 13.04.2018 / 09:45

2 respostas

2

Outra solução awk para evitar a impressão repetida de \n ewlines se a condição não se encontrar em nenhuma linha:

awk '($4=="I-PER"){ printf SEP$1; SEP=" "; C=1; next } 
      C==1{ SEP=""; print ""; C=0} END{print ""}' infile

exemplo de entrada:

Comandante  comandante  NP00000 I-PER
de  de  SPS00   I-PER
la  el  DA0FS0  I-PER
Guardia guardia NP00000 I-PER
Civil   civil   NP00000 I-PER
no I-PER in fourth column
anotherline no I-PER in fourth column
Pamplona    pamplona    NP00000 I-LOC
Poblador    poblador    NP00000 I-PER

A saída é:

Comandante de la Guardia Civil
Poblador
    
por devWeek 13.04.2018 / 11:34
0

Uma solução rápida e um pouco suja com um operador ternário ( condition?true:false ), ele faz o teste que você forneceu e imprime $1 seguido por espaço ou uma nova linha:

awk '{printf $4=="I-PER"?$1" ":"\n"}'

Saída:

$ <test awk '{printf $4=="I-PER"?$1" ":"\n"}'
Comandante de la Guardia Civil 
Poblador

Aqui está uma abordagem alternativa bastante pobre com um array - pelo menos isso não produz linhas vazias como as anteriores não para várias linhas I-PER sucessivas:

awk '{
  if ($4=="I-PER") {a[i++]=$1}
  else if (length(a)>0) {
    for (i in a) {printf a[i]" ";delete a[i]}
    print ""
    }
  }
 END {
  if (length(a)>0) {
    for (i in a) printf a[i]" ";print ""}
  }'

Saída:

$ <test awk '{if($4=="I-PER"){a[i++]=$1}else if(length(a)>0){for(i in a){printf a[i]" ";delete a[i]};print ""}}END{if(length(a)>0){for(i in a)printf a[i]" ";print ""}}'
Comandante de la Guardia Civil 
Poblador
    
por dessert 13.04.2018 / 10:01