awk '{ f[$2] = $1; SUM += $1} END { for (i in f) { print f[i]/SUM, i } }' </tmp/data
Estou tentando traduzir um programa simples para a linha de comando usando utilitários unix. Por exemplo, se eu tenho uma lista de frequências (depois de passar por uniq e ordenar)
5 x
4 y
1 z
Eu quero imprimir, em vez das frequências, a fração do tempo que elas ocorrem:
0.5 x
0.4 y
0.1 z
(Eu tenho um programa python que faz isso, mas eu queria saber se isso poderia ser feito através da própria linha de comando.)
Até agora, tentei calcular a soma
<...>| awk -F" " '{print $1}' | tr '\n' +; echo 0 | bc
mas isso só está me dando a saída 5+1+4+0
sem computá-lo.
EDIT: eu tenho a soma. Eu modifiquei o comando acima para
<...>| awk -F" " '{print $1}' | echo $(tr '\n' +; echo 0) | bc > sum
e o resultado correto é armazenado em soma. Agora eu só quero dividir a lista original por soma e exibi-lo.
Você pode fazer o somatório no awk e a divisão também. Isso será mais simples do que invocar bc
, pois você tem outros dados em cada linha.
Imprime a soma do primeiro campo das linhas de entrada:
awk '{sum += $1} END {print $1}'
Assim, você pode salvar os dados de entrada, calcular a soma e continuar processando os dados.
data=$(…)
sum=$(printf '%s\n' "$data" | awk '{sum += $1} END {print $1}')
printf '%s\n' "$data" | awk -v sum="$sum" '{ $1 /= sum; print }'
Ou você pode faça uma única passagem no awk, mantendo todos os dados na memória .
Tags text-processing bc awk arithmetic