2013-10-03 7 views
38

Sto tentando di trovare la media della seconda colonna di dati utilizzando awk per una classe. Questo è il mio codice corrente, con il quadro fornito il mio istruttore:Utilizza awk per trovare la media di una colonna

#!/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 
} 

e sto ottenendo un errore che dice:

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

Credo di essere vicino, ma io in realtà non hanno alcuna idea di dove per andare da qui. Il codice non dovrebbe essere incredibilmente complesso in quanto tutto ciò che abbiamo visto in classe è stato abbastanza semplice. Per favore mi faccia sapere.

+1

Non sono molto in attesa, ma questo aiuto: http://stackoverflow.com/questions/8434000/awk-calculate-average-or-zero?rq=1 –

risposta

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

Aggiungere i numeri $2 (seconda colonna) in sum (variabili sono automaticamente inizializzati a zero awk) e aumentare il numero di righe (che potrebbe anche essere gestito tramite incorporato NR variabile). Alla fine, se c'è stato almeno un valore letto, stampa la media.

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

Se si desidera utilizzare la notazione baracca, si potrebbe scrivere:

#!/bin/awk 

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

È inoltre possibile controllare il formato della media con printf() e un formato adatto ("%13.6e\n", per esempio).

È inoltre possibile generalizzare il codice di media colonna n (con N=2 in questo esempio) utilizzando:

awk -v N=2 '{ sum += $N } END { if (NR > 0) print sum/NR }' 
1
awk 's+=$2{print s/NR}' table | tail -1 

Sto usando tail -1 per stampare l'ultima riga che dovrebbe avere il numero medio. ..

+2

Un modo molto strano di fare cose. Funziona, ma non riesco a pensare a una buona ragione per usare questa tecnica. –

4

Il tuo errore specifico è con la linea 11:

awk 'BEGIN{sum+=$2}' 

Questa è una riga in cui è stato richiamato awk e il suo blocco BEGIN - ma si è già all'interno di uno script awk, quindi non è necessario specificare awk. Inoltre, si desidera eseguire sum+=$2 su ogni riga di input, in modo da non volerlo all'interno di un blocco BEGIN. Da qui la linea dovrebbe semplicemente leggere:

sum+=$2 

Inoltre, non hanno bisogno di linee:

x=sum 
read name 

il primo crea solo un sinonimo di sum chiamato x e non sono sicuro di quello che fa il secondo, ma nessuno dei due è necessario.

Ciò renderebbe il vostro 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 
} 
risposta di

Jonathan Leffler dà l'awk uno di linea che rappresenta lo stesso codice fisso, con l'aggiunta di controllare che ci sono almeno 1 linee di ingresso (questo si ferma qualsiasi divario per errore zero).Se

+0

Questo ha fatto il trucco, grazie mille! Non mi rendevo conto perché era in uno script awk che non c'era bisogno del comando awk, errore da principiante. Grazie ancora –

+0

@BenZifkin se hai trovato la mia risposta utile potresti accettare la risposta? – imp25

3

Prova questo:

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

NR è un incorporato variabile AWK per contare il no. di record

+0

Benvenuti in overflow dello stack. Se aggiungi una nuova risposta a una domanda di alcuni mesi e che include una risposta accettata, la tua nuova risposta deve fornire alcune nuove informazioni distintive. Non è chiaro che questo faccia il lavoro. Non è ovvio il motivo per cui stai alimentando 'ls -l' in' awk'; né è chiaro il motivo per cui stai usando ':' come separatore di campo. La domanda afferma che è necessario sommare la colonna 2, quindi non è ovvio perché sommi la colonna 5. –

+0

come stampare il nome del file nello stesso momento? –