Агрегация столбцов в Linux - PullRequest
       22

Агрегация столбцов в Linux

2 голосов
/ 24 января 2012

У меня огромный текстовый файл такого формата:

aaa bbb 1      
aaa ccc 2      
aaa ddd 3      
bbb ww 1      
bbb kio 3      

Я хочу агрегировать его, и результат должен быть:

aaa bbb 1/6  
aaa ccc 2/6  
aaa ddd 3/6  
bbb ww 1/4  
bbb kio 3/4  

3-й столбец - вероятность p (y | x)

Как мне это сделать с помощью awk, sed?

Ответы [ 3 ]

6 голосов
/ 24 января 2012
awk 'NR==FNR{a[$1]+=$3;next}{printf("%s/%d\n",$0,a[$1])}' ./infile ./infile

выход

$ awk 'NR==FNR{a[$1]+=$3;next}{printf("%s/%d\n",$0,a[$1])}' ./infile ./infile
aaa bbb 1/6
aaa ccc 2/6
aaa ddd 3/6
bbb ww 1/4
bbb kio 3/4
0 голосов
/ 24 января 2012

Это может работать для вас:

awk 'func p(){for(x=0;x<c;x++)printf("%s/%d\n",l[x],t);k=$1;t=c=0};BEGIN{k=$1};$1!=k{p()};{l[c++]=$0;t+=$3};END{p()}' file
aaa bbb 1/6
aaa ccc 2/6
aaa ddd 3/6
bbb ww 1/4
bbb kio 3/4

NB Предполагается, что файл предварительно отсортирован по ключу.

0 голосов
/ 24 января 2012

Вы можете сделать это за два прохода. Создайте a.tmp , используя:

{ total[$1] += $3}
END {for (group in total) {print group, total[group]}}

Это создает временный файл с итогами группы:

bbb 4
aaa 6

Затем сделайте второй проход с:

BEGIN {
    while ((getline line < "a.tmp") > 0) {
        split(line, fields, " ")
        group[fields[1]] = fields[2]
    }
    close("a.tmp")
}
{   printf("%s/%d\n", $0, group[$1]) }

Это дает результат, который вы ищете:

aaa bbb 1/6
aaa ccc 2/6
aaa ddd 3/6
bbb ww 1/4
bbb kio 3/4
...