1 votes

Valeur manquante lors de la somme dans awk

J'ai des fichiers à deux colonnes, avec la première colonne triée, de sorte que

0 107
1 1
1 141
2 22
3 1
3 222
4 65
5 1
5 53
6 79

Je veux une sortie sans entrées répétées dans la première colonne, et comme deuxième colonne la somme des anciennes valeurs de la deuxième colonne des valeurs répétées de la première colonne. Ma tentative : awk '$1 != p{ if (NR>1) print p, s; p=$1; s=0} {s+=$2} END{print p, s}, qui donne comme sortie

 107
1 142
2 22
3 223
4 65
5 54
6 79

En d'autres termes, la valeur 0 dans la première colonne de la première ligne n'est pas affichée. Qu'est-ce que je rate? Solution en une ligne de préférence.

1voto

Tout d'abord, je recommande d'encadrer l'action de la clause if entre parenthèses. Par exemple, ci-dessous, il est clair que la clause if s'applique uniquement à {print p, s}, et pas à p=$1 et s=0:

awk '$1!=p{if(NR>1){print p, s}; p=$1; s=0}{s+=$2}END{print p, s}'

Cela relève davantage du cosmétique, mais ce n'est pas une erreur.

Votre erreur réside dans le fait de ne pas avoir remarqué que les variables non définies sont traitées à la fois comme 0 et comme une chaîne vide dans les comparaisons. Pour la première ligne du fichier, $1=0. Par conséquent, $1!=p est faux pour la première ligne (puisque p n'est pas défini), ce qui signifie que p n'est toujours pas défini lorsque awk commence à lire la deuxième ligne.

Une solution possible est d'initialiser p à une chaîne vide au début du programme :

awk 'BEGIN{p=""}$1!=p{if(NR>1){print p, s}; p=$1; s=0}{s+=$2}END{print p, s}' fichier

awk '$1!=p{if(NR>1){print p, s}; p=$1; s=0}{s+=$2}END{print p, s}' p="" fichier

Maintenant, la comparaison $1!=p est vraie pour la première ligne, car 0!="".

Sortie :

0 107
1 142
2 22
3 223
4 65
5 54
6 79

0voto

John1024 Points 15663

Essayer :

awk '$1 != p && NR>1{print p, s; s=0} {p=$1; s+=$2} FIN{print p, s}'

Comment ça marche

Chaque fois que nous arrivons à la fin de la séquence, $1 != p && NR>1, nous imprimons p, s et réinitialisons s à zéro.

Pour chaque ligne, nous définissons p sur la première colonne et nous incrémentons s de la deuxième colonne.

Après la dernière ligne, nous imprimons p, s.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X