Programa shell que gera as médias

0
Basicamente, o que eu preciso fazer é escrever um programa chamado avgs que leia linhas do arquivo com dados, onde a linha do título pode estar em qualquer linha dentro dos dados.

Dica: você deve manter um total e contar para cada uma das duas últimas colunas e não deve incluir dados da primeira linha nos totais e das contagens.

Este é o arquivo com os dados:

92876035 SMITZ  S 15 26
95908659 CHIANG R 10 29
SID      LNAME  I T1/20 T2/30
92735481 BRUCE. R 16 28
93276645  YU    C 17 27
91234987 MYRTH  R 15 16

O programa shell irá escrever para stdout a linha: "As médias são 17 e 24"

Isso é o que eu tentei, mas não funciona

count_ppl=0
total=0
while read ?? ?!
do
    total=$((sum+b))
    count_ppl=$((count_ppl+1))
done < filename
avg=$(echo "scale=2;$total/$count_ppl" | bc)
echo "The averages are = $avg"

O "??" e "?!" estão lá ao lado do "while read" porque eu não sei o que colocar lá.

Eu acho que isso provavelmente calcula uma média para uma coluna, mas como eu obteria os dados das colunas e computaria duas médias.

(isso é bum btw).

    
por shawn edward 25.02.2016 / 06:07

1 resposta

3

Não tenho certeza do que você quer dizer com "e não deve incluir dados da primeira linha nos totais e contagens". Você quer dizer que a linha "92876035 SMITZ S 15 26" deve ser excluída ou simplesmente não "somar" "SID LNAME I T1 / 20 T2 / 30"?

O ?? e ?! precisam ser substituídos pelos nomes das variáveis de que você precisa. O último nome de variável mencionado manterá o restante da entrada. Você precisa das duas últimas colunas. No seu caso, há cinco colunas e a declaração while read poderia ser:

while read col1 col2 col3 col4 col5

Em seguida, você precisa verificar se a linha é a linha do título. Neste caso, testarei a palavra SID na primeira coluna:

if [ "$col1" != 'SID' ]

e daqui podemos começar a calcular:

totallines=$((totallines+1))
sumcol4=$((sumcol4+col4))
sumcol5=$((sumcol5+col5))

Finalmente, você pode calcular as médias usando

avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)

Para finalizar, você pode usar o seguinte script:

#!/bin/bash
while read col1 col2 col3 col4 col5
do
  if [ "$col1" != 'SID' ]
  then
      totallines=$((totallines+1))
      sumcol4=$((sumcol4+col4))
      sumcol5=$((sumcol5+col5))
  fi
done < /path/to/inputfile
avgcol4=$(echo "scale=2; $sumcol4/$totallines"|bc)
avgcol5=$(echo "scale=2; $sumcol5/$totallines"|bc)
printf "The averages are %s and %s" $avgcol4 $avgcol5

Outra maneira de fazer isso é usar awk :

awk '{ if ( $1 != "SID" ) { COL4+=$4; COL5+=$5; } } END { LINES=NR-1; printf "The averages are %.2f and %.2f\n", COL4/LINES, COL5/LINES }' < /path/to/inputfile

O comando acima filtra para a linha do título, caso contrário soma a coluna 4 e a coluna 5, e após processar o inputfile, ele ajustará a variável LINES para o número de registros subtraídos por 1 (a linha do título) e imprime a linha de saída.

A versão bash e a awk serão exibidas:

The averages are 14.60 and 25.20
    
por 25.02.2016 / 08:21