Utilitário agregado agrupado (como o SQL GROUP BY)?

5

O Unix tem vários utilitários para executar operações semelhantes a álgebra relacionais em fluxos ( grep , join , cut , itens adicionais com awk ). Existe um utilitário agregado agrupado prontamente disponível (ou instalável na maioria das distribuições Linux)?

O objetivo seria pegar um arquivo com algumas chaves em uma coluna e valores em outra, como:

foo.txt   u1    394082
bar.txt   u2    3948
frob.c    u1    29322

E imprima um arquivo que tenha os valores exclusivos de uma coluna, junto com algum agregado dos valores em outra coluna. Por exemplo, a soma da terceira coluna pelo segundo:

$ aggregate --sum=3 --group-by=2 <data
u1 423404
u2 3948

Existe um utilitário desse tipo (Perl, Awk, etc.), ou algo está esperando para ser escrito?

    
por Michael Ekstrand 01.08.2013 / 17:15

3 respostas

10

Acho que encontrei essa resposta em outra pergunta do StackOverflow, mas achei o "q" bastante útil para essa finalidade: link .

Por exemplo Seu objetivo de exemplo seria atingível assim:

$ q "select c2, sum(c3) from data group by c2"
u1 423404
u2 3948

E como ele usa o sqlite como backend, você pode usar todos os tipos de funções sqlite para fazer cálculos.

    
por 17.10.2013 / 21:49
1

Com algumas restrições, GNU Recutils pode fazer isso. Primeiro, ele precisa ser um arquivo CSV, não TSV (o Recutils não parece gostar de arquivos TSV) e precisa de um cabeçalho. Mas então eu posso fazer:

csv2rec foo.csv |recsel -G user -p 'user,sum(size)' |rec2csv

Não tenho certeza se isso é melhor ou pior que uma linha de expressão Perl ou Awk.

    
por 24.11.2013 / 01:54
1

Se o awk one-liners não conta, talvez você goste do seguinte one-liner shell (bash / ksh):

sort -k2 data | ( while read c1 c2 c3; do if [ "$prev" = "$c2" ]; then
sum=$(expr $c3 + $sum); else if [ $prev ]; then echo $prev $sum; fi;
sum=$c3; prev=$c2; fi; done; echo $prev $sum)

Além de sort e expr (para agrupamento e soma, respectivamente), o ingrediente interessante usado aqui é a instrução read dentro do while. E os parênteses, que criam um subprocesso, necessários para localizar as variáveis $prev e $sum .

    
por 22.03.2014 / 16:31