En utilisant awk pour additionner les valeurs d'une colonne, en fonction des valeurs d'une autre colonne

J'essaie de résumer certains nombres dans une colonne en utilisant awk . Je voudrais résumer la colonne 3 des «forgerons» pour get un total de 212. Je peux résumer toute la colonne en utilisant awk mais pas seulement les «forgerons». J'ai:

 awk 'BEGIN {FS = "|"} ; {sum+=$3} END {print sum}' filename.txt 

Aussi j'utilise du mastic. Merci pour toute aide.

 smiths|Login|2 olivert|Login|10 denniss|Payroll|100 smiths|Time|200 smiths|Logout|10 

 awk -F '|' '$1 ~ /smiths/ {sum += $3} END {print sum}' inputfilename 

L'indicateur -F définit le séparateur de champs; Je l'ai mis entre guillemets car c'est un caractère de shell spécial. Alors $1 ~ /smiths/ applique le {code block} suivant seulement aux lignes où le premier champ correspond au regex /smiths/ . Le rest est le même que votre code.

Notez que puisque vous n'utilisez pas vraiment une regex ici, juste une valeur spécifique, vous pouvez tout aussi bien utiliser:

 awk -F '|' '$1 == "smiths" {sum += $3} END {print sum}' inputfilename 

Qui vérifie l'égalité des strings. Cela équivaut à utiliser l'expression rationnelle /^smiths$/ , comme mentionné dans une autre réponse, qui inclut l'ancre ^ pour seulement faire correspondre le début de la string (le début du champ 1) et l'ancre $ pour correspondre seulement à la fin de la string string. Je ne sais pas à quel point vous êtes familier avec les regex. Ils sont très puissants, mais pour ce cas, vous pouvez utiliser un contrôle d'égalité de string aussi facilement.

Très bien jusqu'à présent. Tout ce que vous avez à faire est d'append un sélecteur avant le bloc pour append la sum. Ici, nous vérifions que le premier argument ne contient que des "smiths":

 awk 'BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}' 

Vous pouvez raccourcir un peu en spécifiant le séparateur de champs en tant qu'option. Dans awk c'est généralement une bonne idée d'initialiser des variables sur la command line:

 awk -F'|' '$1 ~ /^smiths$/ {sum+=$3} END {print sum}' 

Une autre approche consiste à utiliser des arrays associatifs awk, plus d'informations ici . Cette ligne produit la sortie souhaitée:

 awk -F '|' '{a[$1] += $3} END{print a["smiths"]}' filename.txt 

En tant qu'effet secondaire, le tableau stocke toutes les autres valeurs:

 awk -F '|' '{a[$1] += $3} END{for (i in a) print i, a[i]}' filename.txt 

Sortie:

 smiths 212 denniss 100 olivert 10 
 cat filename.txt | grep smiths | awk -F '|' '{sum+=$NF} END {print sum}' 
  • -F pour spécifier le séparateur.
  • $NF est pour la "dernière colonne".