J'essaie de additionner certains nombres dans une colonne en utilisant awk
. Je voudrais additionner juste la colonne 3 des "forgerons" pour obtenir un total de 212. Je peux additionner la colonne entière en utilisant awk
mais pas seulement les "forgerons". J'ai:
awk 'BEGIN {FS = "|"} ; {sum+=$3} END {print sum}' filename.txt
J'utilise aussi PuTTY. 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
-F
flag définit le séparateur de champ; Je l'ai mis entre guillemets simples car il s'agit d'un caractère Shell spécial.$1 ~ /smiths/
applique le {bloc de code} suivant uniquement aux lignes où le premier champ correspond à l'expression régulière /smiths/
.Notez que puisque vous n'utilisez pas vraiment une expression régulière ici, juste une valeur spécifique, vous pouvez tout aussi facilement utiliser:
awk -F '|' '$1 == "smiths" {sum += $3} END {print sum}' inputfilename
Qui vérifie l'égalité des chaînes. Cela équivaut à utiliser l'expression régulière /^smiths$/
, comme mentionné dans une autre réponse, qui comprend le ^
ancre pour faire correspondre uniquement le début de la chaîne (le début du champ 1) et le $
ancre pour correspondre uniquement à la fin de la chaîne. Je ne sais pas dans quelle mesure vous connaissez les expressions rationnelles. Ils sont très puissants, mais dans ce cas, vous pouvez utiliser une vérification d'égalité de chaîne tout aussi facilement.
Une autre approche consiste à utiliser des tableaux associatifs awk, plus d'infos ici . Cette ligne produit la sortie souhaitée:
awk -F '|' '{a[$1] += $3} END{print a["smiths"]}' filename.txt
Comme 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
Production:
smiths 212
denniss 100
olivert 10
Très bien jusqu'ici. Tout ce que vous avez à faire est d'ajouter un sélecteur avant le bloc pour ajouter la somme. Ici, nous vérifions que le premier argument ne contient que des "forgerons":
awk 'BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}'
Vous pouvez raccourcir cela un peu en spécifiant le séparateur de champs en option. Dans awk
c'est généralement une bonne idée d'initialiser des variables sur la ligne de commande:
awk -F'|' '$1 ~ /^smiths$/ {sum+=$3} END {print sum}'
Personnellement, je préférerais garder la section awk
aussi simple que possible et en faire autant que possible sans elle. La logique mixte ne tire pas parti de la puissance des pipelines Unix et est donc plus difficile à comprendre, à déboguer ou à modifier pour des cas d'utilisation étroitement liés.
cat filename.txt | Perl -pe 's{.*|}{}g' | awk '{sum+=$1} END {print sum}'
cat filename.txt | grep smiths | awk -F '|' '{sum+=$NF} END {print sum}'
-F
option pour spécifier le séparateur.$NF
est pour la "dernière colonne".