Utilisation de awk pour additionner les valeurs dune colonne, en fonction des valeurs dune autre colonne

Jessaie 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 ». Jai:

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

Jutilise également du mastic. Merci pour toute aide.

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

Réponse

awk -F "|" "$1 ~ /smiths/ {sum += $3} END {print sum}" inputfilename 
  • Lindicateur -F définit le séparateur de champ; Je lai mis entre guillemets simples car cest un caractère spécial de la coque.
  • Ensuite, $1 ~ /smiths/ applique le {bloc de code} suivant uniquement aux lignes où le premier champ correspond à lexpression régulière /smiths/.
  • Le reste est le même que votre code.

Notez que puisque vous nutilisez pas vraiment une regex ici, juste une valeur spécifique, vous pouvez tout aussi facilement utilisez:

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

Qui vérifie légalité des chaînes. Cela équivaut à utiliser lexpression régulière /^smiths$/, comme mentionné dans un autre réponse, qui inclut lancre ^ pour correspondre uniquement au début de la chaîne (le début du champ 1) et lancre $ uniquement correspond à la fin de la chaîne. Je ne sais pas à quel point vous êtes familier avec les expressions régulières. Elles sont très puissantes, mais dans ce cas, vous pouvez utiliser une vérification dégalité des chaînes tout aussi facilement.

Commentaires

  • Au fait, ma référence awk préférée est grymoire.com/Unix/Awk.html . Page très utile .
  • Merci @Wildcard! Jai pu agréger parfaitement une taille non compressée de fichiers particuliers dans une grande archive zip en fonction de vos conseils 🙂

Réponse

Une autre approche consiste à utiliser des tableaux associatifs awk, plus dinfos 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 

Résultat:

smiths 212 denniss 100 olivert 10 

Commentaires

  • Ceci est la bonne réponse

Réponse

Très bien jusquà présent. Tout ce que vous avez à faire est dajouter un sélecteur avant le bloc pour ajouter la somme. Ici, nous vérifions que le premier argument ne contient que « smiths »:

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

Vous pouvez raccourcir un peu cela en spécifiant le séparateur de champ comme option. Dans awk, il est généralement judicieux d’initialiser les variables sur la ligne de commande:

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

Réponse

Personnellement, je préférerais garder la section awk aussi simple que possible et faire tout ce que vous pouvez sans elle . La logique combinée 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}" 

Answer

cat filename.txt | grep smiths | awk -F "|" "{sum+=$NF} END {print sum}" 
  • -F option pour spécifier le séparateur .
  • $NF correspond à la « dernière colonne ».

Commentaires

  • cat et grep ne sont pas nécessaires ici.
  • Pourquoi grep est-il inutile @Andrey? OP souhaite ajouter uniquement des lignes " smiths ". Vous ' devez modifier linstruction awk, nest-ce pas?
  • @EL oui, linstruction awk doit être modifiée en /smiths/{...} si lappel grep nest pas là. Il sagit dune modification triviale, mais elle offre des avantages significatifs: diminue le nombre de processus en cours dexécution, simplifie le contrôle des erreurs et rend le code plus clair.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *