Una piccola e semplice script di shell per calcolare le medie

Qualcuno può dirmi che cosa sto facendo di sbagliato?

#!/bin/sh

if [ $# = 0 ]
then
    echo "Usage: $0 <filename>"
    exit 1
fi

sum=0
count=0

while [ $0 != 0 ]
do
        sum="$sum"+"$2"
        count="$count"+ 1

done
if [ "$count" != 0 ]
then
        avg="$sum"/"$count"
        printf "Sum= $sum \n Count= $count  \n Avg= $avg"
        exit 0
else
        printf "Sum= $sum \n Count= $count  \n Avg= undefined"
        exit 0
fi
exit 1

Ecco l’output quando provo a testare il codice:

./average

sum: =: No such file or directory
sum: 0: No such file or directory
./average: 11: count: not found
[: 18: !=0: unexpected operator
./average: 25: Syntax error: Unterminated quoted string

In sostanza se ho avuto un file che sembrava qualcosa di simile a questo:

FirstPerson 23 

SecondPerson 36

ThirdPerson 22

Voglio essere in grado di leggere nel mio programma e lo hanno di uscita:

Sum = FirstPerson+SecondPerson+ThirdPerson

Count = NumberofPeople

Average = Sum/Count
La risposta è accettato non funziona perche ‘expr’ non fare la divisione in virgola mobile. Eseguire expr 5 / 2 e vedrai che la risposta data non e ‘2.5’, ma piuttosto ‘2’. Se davvero si vuole attaccare con Bash (non la mia raccomandazione, vedere stackoverflow.com/questions/1886157/…), allora avrai bisogno di chiamare un programma come ‘bc’ che fa fare matematica in virgola mobile. Tuttavia, a meno che questo è un esercizio di apprendimento in bash, non vedo perché non andare con un 1-liner in awk?
Se si desidera una buona Bash risposta, allora ti suggerisco di accettare questa: stackoverflow.com/questions/1886157/…
Grazie per le informazioni utili a tutti. Non mi rendevo conto di quanto è facile usare AWK per questo compito.

OriginaleL’autore | 2009-12-11

8 risposte

  1. 2

    il codice riportato di seguito funziona, probabilmente si può ottimizzare la pena se si vuole (o usare awk, perl, ecc):

    #!/bin/bash
    
    if [ $# -ne 1 ]; then
            echo "Usage: \"$0\" <filename>"
            exit
    fi
    
    if [ ! -f $1 ]; then
            echo "$1 file not found."
            echo "Usage: $0 <filename>"
            exit
    fi
    
    sum=0
    count=0
    arq=$1
    
    while read line
    do
            num=`echo ${line#* }`
            sum=`expr $sum + $num`
            count=`expr $count + 1`
    done < "$arq"
    
    if [ "$count" != 0 ]
    then
            avg=`expr $sum /$count`
            printf "Sum= \"$sum\" \n Count= \"$count\"  \n Avg= \"$avg\""
            exit 0
    else
            printf "Sum= \"$sum\" \n Count= \"$count\"  \n Avg= undefined"
            exit 0
    fi
    Anche se questo è accettato risposta è: “NON corretto, perché ‘expr’ non fare la divisione in virgola mobile. La media calcolata nel presente codice solo essere corretto se $count è un numero intero multiplo di $somma. Provare expr 5 / 2 e vedrai che la risposta è 2, e non il valore corretto di ‘2.5’
    siegex, penso che si sono frettolosamente supponendo che la persona che chiede la domanda vuole un punto mobile di risposta… che può o non può essere il caso, in quanto egli non specificare nella domanda.
    Vorrei sostengono che una Media che è stato troncato a un numero intero, non è la Media, ma piuttosto di un Modulo.
    Una media aritmetica deve essere fatto in real, non interi (cioè, senza divisione di numeri interi). Altrimenti, come SiegeX punti, non è una media aritmetica.

    OriginaleL’autore Peter Carrero

  2. 16
     awk '{sum+=$2}END{printf "Sum=%d\nCount=%d\nAve=%.2f\n",sum,NR,sum/NR}' ave.txt

    Prima di tutto, Bash non si può fare la divisione intera, sarà necessario inviare la matematica per uno strumento come ‘bc’ o basta usare awk a fare tutto quanto è molto potente, dopo tutto, che l’intero script del tuo stato trasformato in un 1-liner.

    Di Ingresso Del Campione

    $ cat ave.txt 
    FirstPerson 23 
    SecondPerson 36 
    ThirdPerson 22 
    

    Risultato

    Somma=81 
    Count=3 
    Ave=27.00 
    
    Battere me da un secondo 🙂
    … e ha scritto molto meglio di script. Voglio togliere il mio, l’indegno AWK concorrente.

    OriginaleL’autore SiegeX

  3. 6

    Non so il tuo script di shell, ma so che si deve usare lo strumento giusto per il lavoro. Che strumento è AWK. È stato progettato specificamente per questo compito e, se si utilizza UNIX (o Linux, o Mac OS X o quello che è) è installato nel sistema. Questo è il one-liner:

    awk '{ sum+=$2; count+=1 } END {print "Sum =",sum; print "Count =",count; print "Average= ",sum/count}' test2.dat 

    Leggere il guida per AWK. La filosofia di UNIX è NON REINVENTARE LA RUOTA. Utilizzare gli strumenti giusti, amico.

    Buona fortuna,

    nel mio esempio ho scritto un file chiamato test2.dat con i dati che hai fornito.
    Haha, così ho fatto. Quasi identico, tranne per il fatto che awk già fornisce un conteggio con ‘NR’.

    OriginaleL’autore Escualo

  4. 2

    provare questo

    count_ppl=0
    sum=0
    while read a b
    do
       sum=$((sum+b))
       count_ppl=$((count_ppl+1))
    done < file
    echo "Sum=$sum"
    echo "Count=$count_ppl"
    avg=$(echo "scale=2;$sum/$count_ppl" | bc)
    echo "Average=" $avg
    Buona bash soluzione, anche se può essere ottimizzato un po ‘ di più usando ((sum+=b)) e ((count_ppl++)) invece di due righe che hai sopra.
    ottimizzato? non capisco. qualsiasi riferimento o la prova che dice + = ++ o finisce più veloce? se è questo che intendi.
    Ottimizzato in termini di battitura e la leggibilità del codice IMHO. Non credo ci sarebbe molta differenza, a tutti, tra i due l’efficienza saggio.
    quindi non importa. Le sue personali preferenze. Solo un qns, non fa altro supporto di shell += operatore di assegnazione?

    OriginaleL’autore ghostdog74

  5. 1

    Per cominciare, non si dovrebbe avere spazio su entrambi i lati di un =

    Wow. Credo che tu possa dire che io di solito non scrivere script di shell…haha. Grazie uomo.

    OriginaleL’autore pavium

  6. 1

    L’errore “non terminata stringa tra virgolette” è di per sé esplicativa

    printf "Sum= \"$sum\" \n Count= \"$count\"  \n Avg= "\$avg\""

    Dovrebbe essere

    printf "Sum= \"$sum\" \n Count= \"$count\"  \n Avg= \"$avg\""

    OriginaleL’autore Anand Shah

  7. 1

    Guardando lo script non sembra essere molto che si sta facendo correttamente.
    Mi consiglia di guardare alcune Bash come e seguire semplici passi per arrivare a fare quello che si aspettano.

    1. senza spazi dopo l’assegnazione di variabile, dovrebbe essere sum= e così via
    2. while [ ! -f $1 ] potrebbe effettivamente fare qualcosa ma non quello che ci si aspetta
    3. read -p "Re-enter the filename and hit <Enter>: " sicuramente non fa quello che ci si aspetta
    4. e così via

    OriginaleL’autore stefanB

  8. 1
                c program for simple interest
    
     #include<stdio.h>
     int main(void)
      { 
        int p,r,t,s;
        printf("enter the principle value");
        scanf("%d",&p);
        printf("enter the rate or interest");
        scanf("%d",&r);
        printf("enter the time period ");
        scanf("%d",&t);
        s=p*t*r/100;
        printf("the simple interest is %d",&s);
      }     
    Questo è un C risposta. Totalmente separata dalla lingua viene chiesto (bash)

    OriginaleL’autore

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *