2012-11-07 16 views
7

Mam 500 plików z nazwą fort.1, fort.2 ... fort.500. Każdy plik zawiera 800 danych poniżej:obliczanie średniej za pomocą awk z wielu plików

1 0,485
2 0,028
3 0,100
4 0,979
5 0,338
6 0,891
7 0,415
8 0,368
9 0,245
10 0.489

Chcę uzyskać średnią każdego wiersza drugiej kolumny z każdego pliku. Innymi słowy, zdobądź średnią pierwszej kolumny z drugiej kolumny ze wszystkich plików i przechowuj ją w "output.file". Następnie zdobądź średnią z drugiej kolumny drugiej linii i przechowuj ją w tym samym pliku "output.file". Próbowałem za pomocą polecenia wklej, ale nie dostałem tego, co chcę. Czy jest jakiś sposób zrobić w AWK?

Doceń każdą pomoc. Dzięki

Odpowiedz

1

Moje zrozumienie: każdy plik to zestaw pomiarów w określonej lokalizacji. Chcesz agregować pomiary we wszystkich lokalizacjach, uśredniając wartość tego samego wiersza w każdym pliku w nowym pliku.

Zakładając, że pierwsza kolumna może być traktowany jako identyfikator dla danego rzędu (i nie 800 pomiarów w pliku):

cat fort.* | awk ' 
BEGIN { 
    for (i = 1; i <= 800; i++) 
     total[i] = 0 
} 

{ total[$1] += $2 } 

END { 
    for (i = 1; i <= 800; i++) 
     print i, total[i]/500 
} 
' 

Najpierw zainicjować szereg do przechowywania sumy na rzędzie na wszystkich akta.

Następnie przechodzimy przez połączone pliki. Używamy pierwszej kolumny jako klucza do wiersza i sumujemy ją do tablicy.

Na koniec przechodzimy przez tablicę i wyprowadzamy średnią wartość z wiersza do wszystkich plików.

+0

W tym kodzie co rozumiem jest to, że w pierwszych wszystkich wartości z plik fort.1 zachowaj w tablicy "total". Następnie przechodzi do drugiego pliku fort.2 i zachowuje całkowitą tablicę. (Na przykład), to zrobi (łącznie [1] + ogółem [1]/2) z pierwszego i drugiego pliku, aby uzyskać średnią. Ale nie rozumiem tego ... Przepraszam, jeśli zrozumiałem niewłaściwie. – Vijay

+0

Edytowane w celu odzwierciedlenia moich założeń dotyczących problemu. –

+0

Dzięki za szybką odpowiedź. Pozwól mi jeszcze raz wyjaśnić, czego chcę. Każdy plik (łącznie 500 plików) zawiera dwie kolumny (pierwsza kolumna i druga kolumna) oraz 800 wierszy linii.Chcę, aby pierwszy wiersz, druga kolumna każdego pliku (wszystkie 500 plików) zostały dodane i obliczyć średnią oraz zapisać w nowym pliku jako average.output. Następnie przechodzi do drugiej linii, drugiej kolumny wszystkich plików (500 plików) i obliczyć średnią i zapisać w average.output. I trwa, dopóki plik average.output nie zawiera 800 linii. Życzę ci tego wyjaśnienia. Przepraszam, jeśli moje pytanie w poście wprawiło Cię w zakłopotanie. Z góry dziękuję. – Vijay

2

Zakładając, że pierwsza kolumna jest ID:

cat fort.* | awk '{sum[$1] += $2; counts[$1]++;} END {for (i in sum) print i, sum[i]/counts[i];}' 
5

Oto szybki sposób za pomocą paste i awk:

paste fort.* | awk '{ for(i=2;i<=NF;i+=2) array[$1]+=$i; if (i = NF) print $1, array[$1]/NF*2 }' > output.file 

jak w niektórych innych odpowiedzi; oto inny sposób ale ten wykorzystuje sort dostać wyjście numerycznie posortowaną:

awk '{ sum[$1]+=$2; cnt[$1]++ } END { for (i in sum) print i, sum[i]/cnt[i] | "sort -n" }' fort.* 
7

awk bez założeniu na 1 kolumnę:

awk '{a[FNR]+=$2;b[FNR]++;}END{for(i=1;i<=FNR;i++)print i,a[i]/b[i];}' fort.* 
+0

Czy ten kod uwzględnia wszystkie "pierwszą linię wszystkich plików wejściowych (fort.1, fort.2 ...)" i obliczyć średnią, a następnie przechodzi do drugiej linii wszystkich plików (fort.1, fort.2 ... .) aż do 800 linii z każdego pliku? Potrzebuję wyjaśnienia, aby zrozumieć, co faktycznie robi ten kod. Dzięki – Vijay

+0

@Vijay: Naprawdę to ... zmodernizowałem z fortem *, aby było bardziej jasne. Możesz przetestować go na małym próbnym pliku, aby potwierdzić ... – Guru

+0

Guru, ten kod działa poprawnie. Dziękuję Ci. Dodatkowo trzeba dodać coś małego. Mam pliki z nazwami fort 1, fort.2 i tak dalej. Boję się, jeśli postawię fort. *, Będzie czytać fort 1, fort.10, fort.100 zamiast fort.1, fort.2 i tak dalej. Jak można to leczyć? Dzięki – Vijay

Powiązane problemy