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
etgrep
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.