web-dev-qa-db-fra.com

Utilisez awk pour trouver la moyenne d'une colonne

J'essaie de trouver la moyenne de la deuxième colonne de données en utilisant awk pour une classe. Ceci est mon code actuel, avec le framework fourni par mon instructeur:

#!/bin/awk

### This script currently prints the total number of rows processed.
### You must edit this script to print the average of the 2nd column
### instead of the number of rows.

# This block of code is executed for each line in the file
{
x=sum
read name
        awk 'BEGIN{sum+=$2}'
        # The script should NOT print out a value for each line
}
# The END block is processed after the last line is read
END {
        # NR is a variable equal to the number of rows in the file
        print "Average: " sum/ NR
        # Change this to print the Average instead of just the number of rows
}

et je reçois une erreur qui dit:

awk: avg.awk:11:        awk 'BEGIN{sum+=$2}' $name
awk: avg.awk:11:            ^ invalid char ''' in expression

Je pense que je suis proche mais je ne sais vraiment pas où aller à partir de maintenant. Le code ne devrait pas être incroyablement complexe car tout ce que nous avons vu en classe a été assez basique. S'il vous plaît, faites-moi savoir.

47
Ben Zifkin

Votre erreur spécifique est avec la ligne 11:

awk 'BEGIN{sum+=$2}'

Ceci est une ligne où awk est appelé et son bloc BEGIN est spécifié - mais vous êtes déjà dans un script awk, vous n'avez donc pas besoin de spécifier awk. Aussi, vous voulez exécuter sum+=$2 sur chaque ligne d’entrée, vous ne le souhaitez donc pas dans un bloc BEGIN. La ligne devrait donc simplement se lire:

sum+=$2

Vous n'avez pas non plus besoin des lignes:

x=sum
read name

le premier crée simplement un synonyme pour sum nommé x et je ne suis pas sûr de ce que le second fait, mais aucun n'est nécessaire.

Cela rendrait votre script awk:

#!/bin/awk

### This script currently prints the total number of rows processed.
### You must edit this script to print the average of the 2nd column
### instead of the number of rows.

# This block of code is executed for each line in the file
{
    sum+=$2
    # The script should NOT print out a value for each line
}
# The END block is processed after the last line is read
END {
    # NR is a variable equal to the number of rows in the file
    print "Average: " sum/ NR
    # Change this to print the Average instead of just the number of rows
}

La réponse de Jonathan Leffler donne à l'awk une ligne qui représente le même code fixe, avec la vérification qu'il existe au moins une ligne d'entrée (cela arrête toute division par zéro erreur). Si

9
imp25
awk '{ sum += $2; n++ } END { if (n > 0) print sum / n; }'

Ajoutez les nombres dans $2 (Deuxième colonne) dans sum (les variables sont auto-initialisées à zéro par awk) et incrémentez le nombre de lignes (pouvant également être gérées via variable intégrée NR). A la fin, s'il y a au moins une valeur lue, affiche la moyenne.

awk '{ sum += $2 } END { if (NR > 0) print sum / NR }'

Si vous voulez utiliser la notation Shebang, vous pouvez écrire:

#!/bin/awk

{ sum += $2 }
END { if (NR > 0) print sum / NR }

Vous pouvez également contrôler le format de la moyenne avec printf() et un format approprié ("%13.6e\n", Par exemple).

Vous pouvez également généraliser le code pour faire la moyenne de la Nème colonne (avec N=2 Dans cet exemple) en utilisant:

awk -v N=2 '{ sum += $N } END { if (NR > 0) print sum / NR }'
107
Jonathan Leffler

Essaye ça:

ls -l  | awk -F : '{sum+=$5} END {print "AVG=",sum/NR}'

NR est une variable intégrée AWK pour compter le non. des enregistrements

3
Pradipta
awk 's+=$2{print s/NR}' table | tail -1

J'utilise tail -1 pour imprimer la dernière ligne qui devrait avoir le nombre moyen ...

1
iamauser