web-dev-qa-db-fra.com

Fusionner les valeurs de lignes consécutives si elles ont les mêmes valeurs sur une colonne différente (AWK)

Je dois combiner la première valeur ($1) de lignes consécutives si leur quatrième valeur ($4) est identique (I-PER).

J'ai réussi à filtrer les valeurs dont j'ai besoin simplement en utilisant awk:

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

J'ai également trouvé comment fusionner des lignes avec des valeurs de colonnes en double, mais non consécutives.

Exemple (entrée):

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

Exemple (sortie):

Comandante de la Guardia Civil
Poblador
2
Mikel SS

Une autre solution awk pour éviter d’imprimer de manière répétée \nlignes si la condition ne s’est réunie dans aucune des lignes:

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

exemple d'entrée:

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

La sortie est:

Comandante de la Guardia Civil
Poblador
2
αғsнιη

Une solution rapide et quelque peu sale avec un opérateur ternaire (condition?true:false), elle effectue le test que vous avez fourni et imprime soit $1 suivi d'un espace ou d'un saut de ligne:

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

Sortie:

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

Voici une approche alternative assez médiocre avec un tableau - au moins, cela ne produit pas de lignes vides, contrairement à ce qui est décrit ci-dessus pour plusieurs lignes non -I-PER successives:

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 ""}
  }'

Sortie:

$ <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
0
dessert