2012-05-09 11 views
23

My file.txt wygląda następująco:awk suma kolumny i drukowania, które sumują się na każdej linii wejścia

1 12 
2 18 
3 45 
4 5 
5 71 
6 96 
7 13 
8 12 

mogę podsumować drugą kolumnę tak:

awk '{ sum += $2 } END { print sum }' file.txt

272

Jaki jest najmilszy sposób, aby wydrukować tę sumę w każdym wierszu? To co ja spodziewałem:

1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 
+0

Dziękuję wszystkim! Kilka bardzo przydatnych odpowiedzi tutaj. Twoje zdrowie. – Steve

Odpowiedz

19

standardowy rodzaj awk sposób.

$ awk 'FNR==NR{sum+=$2;next}; {print $0,sum}' file.txt{,} 
1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 
+0

Sufiks wieloznaczny '{,}' jest skrótem do dwukrotnego powtarzania nazwy pliku wejściowego. To nie jest standardowa powłoka Bourne'a. – tripleee

+1

To jest kanoniczne AWK i nie przechowuje pliku w pamięci. To powinna być zaakceptowana odpowiedź. –

+0

@DennisWilliamson, Witaj, czy mógłbyś wyjaśnić, na podstawie jakiego powodu ten awk nie przechowuje pliku w pamięci?dzięki –

1

Offtopic, ale w Perlu można zrobić:

perl -nale '$s+=$F[1];push(@a,$_);END{print $_." $s" for(@a);}' file.txt 
7

Można użyć:

awk -v xyzzy=$(awk '{sum+=$2}END{print sum}' file.txt) 
    '{print $0" "xyzzy}' file.txt 

To niestety oznacza, przeżywa informacji dwa razy:, ale ponieważ musisz zrobić to raz, zanim uzyskasz całość, nie ma na to realistycznego sposobu. Każde rozwiązanie będzie wymagać przechowywania informacji przed wyprowadzeniem czegokolwiek (zarówno w tablicach, jak i wracaniu do pliku).

Wewnętrzna awk ustala całkowitą i zewnętrzną awk przypisuje ją do zmiennej, która może być drukowana wraz z każdą linią.

Stosując że do pliku:

a 1 
b 2 
c 3 
d 4 
e 5 

daje, bo 1 + 2 + 3 + 4 + 5 jest równa 15:

a 1 15 
b 2 15 
c 3 15 
d 4 15 
e 5 15 
+0

@codaddict: czy miałeś na myśli "... _can't_ store ..."? – paxdiablo

+0

yes..Nie wiem co się tam stało :) – codaddict

3

Stosować tablice

{ 
    a[NR] = $0 
    sum += $2 
} 
END { 
    for (x = 1; x <= NR; x++) { 
     print a[x], sum 
    } 
} 

Wyjście

$ awk -f s.awk file.txt 
1 12 272 
2 18 272 
3 45 272 
4 5 272 
5 71 272 
6 96 272 
7 13 272 
8 12 272 

Czytaj więcej w Gnu Awk Manual

1

Brzydkie rozwiązanie:

awk '{printf "%s ", $0}{system(" awk \047 {sum+=$2}END{print sum} \047 file ")}' file 
1

awk, tak, głowy i wklej.

$ yes "`<file.txt awk '{ sum += $2 } END { print sum }'`" | head -n `<file.txt wc -l` | paste -d ' ' file.txt -