2013-10-03 11 views
38

Próbuję znaleźć średnią z drugiej kolumny danych przy użyciu klasy awk. To jest mój aktualny kod, z ramami mój instruktor przewidzianym:Użyj awk, aby znaleźć średnią z kolumny

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

i Dostaję błąd, który mówi:

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

myślę, że jestem blisko, ale naprawdę nie mam pojęcia, gdzie iść stąd. Kod nie powinien być niewiarygodnie złożony, ponieważ wszystko, co widzieliśmy na zajęciach, było dość proste. Proszę daj mi znać.

+1

Nie jestem zbytnio na awk, ale to pomaga: http://stackoverflow.com/questions/8434000/awk-calculate-average-or-zero?rq=1 –

Odpowiedz

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

Dodać numery $2 (druga kolumna) w sum (zmienne są automatycznie inicjowany na zero awk) oraz zwiększać liczbę rzędów (która może być obsługiwany za pośrednictwem wbudowanej zmiennej nr). Na koniec, jeśli została odczytana co najmniej jedna wartość, wydrukuj średnią.

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

Jeśli chcesz użyć notacji shebang, można napisać:

#!/bin/awk 

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

Można również kontrolować format średniej z printf() i odpowiedniego formatu ("%13.6e\n", na przykład).

Można też uogólniać kod średnich kolumnę n-tym (z N=2 w tej próbce) za pomocą:

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

Używam tail -1 wydrukować ostatnią linię, która powinna mieć średnią liczbę. ..

+2

Bardzo dziwny sposób robienia rzeczy. Działa, ale nie mogę wymyślić dobrego powodu, dla którego użyłbym tej techniki. –

4

Twój specyficzny błąd jest z linii 11:

awk 'BEGIN{sum+=$2}' 

To jest linia, w której wywoływana jest awk, a jej blok BEGIN jest określony - ale już znajdujesz się w skrypcie awk, więc nie musisz określać awk. Również chcesz uruchomić sum+=$2 w każdym wierszu wejścia, więc nie chcesz go w bloku BEGIN. Stąd linia powinna po prostu przeczytać:

sum+=$2 

też nie potrzebują linie:

x=sum 
read name 

pierwszy prostu tworzy synonimem sum nazwie x i nie jestem pewien, co drugi robi, ale nie są potrzebne.

byłoby to zrobić skrypt 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 
} 
odpowiedź

Jonathana Lefflera daje awk jedną wkładkę, która reprezentuje ten sam kod stały, z dodatkiem sprawdzenia, że ​​istnieją co najmniej 1 linii wejściowych (to zatrzymuje każdy błąd dzielenia przez zero).Jeśli

+0

To się udało, dziękuję bardzo! Nie zdawałem sobie sprawy, ponieważ w skrypcie awk nie było potrzeby polecenia awk, debiutancki błąd. Jeszcze raz dziękuję –

+0

@BenZifkin, jeśli uważasz, że moja odpowiedź jest przydatna, czy możesz zaakceptować odpowiedź? – imp25

3

Spróbuj tego:

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

NR jest wbudowane zmienna AWK liczyć nie. rekordów

+0

Witamy w przepełnieniu stosu. Jeśli dodasz nową odpowiedź na pytanie, które ma kilka miesięcy i zawiera akceptowaną odpowiedź, nowa odpowiedź musi zawierać pewne charakterystyczne nowe informacje. Nie jest jasne, czy to działa. Nie jest oczywiste, dlaczego karmisz 'ls -l' w' awk'; ani nie jest jasne, dlaczego używasz ':' jako separatora pól. Pytanie mówi, że należy zsumować kolumnę 2, więc nie jest oczywiste, dlaczego sumujesz kolumnę 5. –

+0

jak wydrukować nazwę pliku w tym samym czasie? –