/ / Column Read e Average (BASH) - bash

Colonna Lettura e media (BASH) - bash

quindi mi sto occupando di problemi di media della colonna

Ho diverse colonne di numeri,

1 2 3 4 5
2 3 4 5 6
8 4 5 6 7
9 8 7 6 5
1 9 9 9 2

Quello che voglio fare è prendere una media di ogni colonna in modo che cedano

4 5 5 6 5

La parte sommatoria non è un problema, sono in grado di ottenere la somma di ogni colonna, ma in qualche modo sto avendo problemi nel conteggio del numero di colonne (variabile $ x) Ecco il mio codice

while read line; do
x = 0
read -a array <<< "$line"

for i in "${!array[@]}"
do
column[${i}]=$((${column[${i}]}+${array[$i]}))
((x++))
done
done < $TMP

for sum in ${column[@]}
do
average=`expr $sum / $x`
remainder=`expr $sum % $x`
mult=`expr $remainder * 10`
fracvalue=`expr $mult / $x`
echo $x
echo $average
echo $sum
echo $remainder
echo $mult
echo $fracvalue
done

Le ultime righe sono per i miei testscopi, qui $ X continua a mostrare 1 invece di 5. Ecco perché svuota tutte le altre variabili Qualcuno sa dov'è il difetto in questo codice? Apprezzo davvero il tuo aiuto. Grazie

risposte:

0 per risposta № 1

Un altro approccio:

#!/bin/bash

declare -ia sum        # declare array of integers
declare -i lines=0     # declare integer to count lines

# read file to array and sum values
while read -ra array; do
for ((i=0; i<${#array[@]};i++)); do
sum[$i]+=${array[$i]}
done
lines+=1
done < file

# print averages
for ((j=0; j<$i;j++)); do
echo -n "$((${sum[$j]}/$lines)) "
done

Produzione:

4 5 5 6 5

0 per risposta № 2

Il problema è nella linea x = 0 dovrebbe essere x=0 e fare ((x+1)) come let "x+=1" dovrebbe funzionare.


0 per risposta № 3

Forse il tuo file non ha lo stesso numero di righe in ogni colonna.

while read line; do
read -a array <<< "$line"

for i in "${!array[@]}"
do
column[${i}]=$((${column[${i}]}+${array[$i]}))
((x[${i}]++))
done
done < $TMP

for i in ${!column[@]}
do
sum=${column[$i]}
x=${x[${i}]}
#your calcul
done

0 per risposta № 4

Il problema iniziale, a parte alcune peculiarità della sintassi, era il ripristino di x su ciascun read che ti ha fatto perdere il conteggio delle righe. Inoltre, il tuo array è un indicizzato array, non un associativo array.

Fare le piccole regolazioni e declareall'inizio delle variabili (per suggerire a bash sono numeri interi o matrici), funziona come pianificato. Nota: non c'è bisogno di a stringa here per assegnare l'array, basta usare la normale sintassi dell'array. Inoltre, per gli array indicizzati, non è necessario dereferenziare la variabile all'interno [ ], semplicemente ${array[i]} è ok.

Mentre l'uso di expr va bene (vecchio, lento, ma portatile e fine), è possibile utilizzare la sintassi aritmetica bash per i calcoli dei parametri alla fine. (hai già matrici). Infine, è meglio servirne l'inizializzazione column[$i]=0 sul primo ciclo di lettura. Puoi farlo con una semplice bandiera:

#!/bin/bash

declare -i ncols=0
declare -i x=0
declare -a column

while read -r line; do

array=( $line )
[ $ncols -eq 0 ] && ncols=${#array[@]}

for ((i = 0; i < ncols; i++))
do
[ $x -eq 0 ] && column[$i]=0
column[$i]=$(( ${column[i]} + ${array[i]}))
done

((x++))

done < "$1"

for sum in ${column[@]}
do
average=`expr $sum / $x`
remainder=`expr $sum % $x`
mult=`expr $remainder * 10`
fracvalue=`expr $mult / $x`
echo $x
echo $average
echo $sum
echo $remainder
echo $mult
echo $fracvalue
done

exit 0

Produzione

$ bash colavg.sh dat/colavg.txt
5
4
21
1
10
2
5
5
26
1
10
2
5
5
28
3
30
6
5
6
30
0
0
0
5
5
25
0
0
0