Você pode usar o seguinte script awk
:
$ awk '
{ a[$1]+=$2 }
END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)
No entanto, a ordem da saída não será mais preservada com essa abordagem. No entanto, desde que os dados estejam em ordem numérica de data, um simples sort
no final realinhará a saída.
Exemplo
Supondo dados de amostra.
$ cat sample.txt
date Value
01/01/2000 2
01/01/2000 2
01/02/2000 6
01/03/2000 5
01/03/2000 4
O script acima gerará os resultados da seguinte forma:
$ awk '
{ a[$1]+=$2 }
END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)
01/02/2000 6
01/01/2000 4
01/03/2000 9
A execução da saída por meio de sort
realinha os dados.
$ awk '
{ a[$1]+=$2 }
END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt)|sort
01/01/2000 4
01/02/2000 6
01/03/2000 9
O cabeçalho do arquivo original pode ser adicionado de volta:
$ (head -n 1 sample.txt; awk '{a[$1]+=$2}END{for(val in a) printf("%s %s\n", val, a[val])}' <(tail -n +2 sample.txt)|sort)
date Value
01/01/2000 4
01/02/2000 6
01/03/2000 9
Você pode desdobrar isso um pouco para facilitar a leitura:
$ (
head -n 1 sample.txt
awk '
{ a[$1]+=$2 }
END{ for(val in a) printf("%s %s\n", val, a[val]) }
' <(tail -n +2 sample.txt) | sort
)
date Value
01/01/2000 4
01/02/2000 6
01/03/2000 9
UPDATE # 1
Com base no feedback de @StephaneChazelas nos comentários, simplifiquei um pouco mais o meu exemplo. Foi capaz de eliminar o tail ...
movendo-o dentro do bloco awk
usando isso, ( NR==1{ next }
). Isso irá pular a primeira linha de sample.txt
.
Eu também movi o | sort
dentro do bloco END{...}
. Isso ainda será sort
da saída gerada por awk
para realinhar os dados com base nas datas. Como awk
agora está chamando /bin/sort
, ele é colocado entre aspas duplas.
$ awk '
NR==1{ print; next }
{ a[$1]+=$2 }
END{ for(val in a) print val, a[val] | "sort" }
' sample.txt
)
date Value
01/01/2000 4
01/02/2000 6
01/03/2000 9