Bash help

Why wont this work?

TOTAL=99
tier1count=11
tier2count=22
tier3count=67
for xx in 1 2 3 ; do  
echo \"Tier $xx\",\"$teir${xx}count\",\"$[ 100 * $tier${xx}count / $TOTAL ]%\"
done

How do I get it to see/resolved the nested variables?

The closest I got was this…

for xx in 1 2 3 ; do  
echo \"Tier $xx\",\"$(echo '$'tier${xx}count)\",\"$[ 100 * $tier1count / $TOTAL ]%\"
done

which gave output like:

"Tier 1","$tier1count","11%"
"Tier 2","$tier2count","11%"
"Tier 3","$tier3count","11%"

I am not totally sure what you are going for, but I think you would be better off using an array instead of trying to dynamically name variables:

clifford@ubuntu-scratch:~$ COUNTS[1]=11; COUNTS[2]=22; COUNTS[3]=67; TOTAL=99; \
for xx in 1 2 3; do \
    local_count=${COUNTS[$xx]}; \ 
    local_percent=$((100 * $local_count / $TOTAL)); \
    printf "Tier %i, tier%icount = %i, Percent %i\n" $xx $xx $local_count  $local_percent; \
done

Tier 1, tier1count = 11, Percent 11
Tier 2, tier2count = 22, Percent 22
Tier 3, tier3count = 67, Percent 67

Because of integer rounding and the numbers you chose, each element count is its percentage of the total.

Edit: to add line breaks

1 Like

#!/bin/bash
TOTAL=99
tierCount=(11 22 67)
calc(){ awk “BEGIN { print “$*” }”; }

val=1
for i in ${tierCount[@]}
do
result=calc $i/$TOTAL
echo “$i”
echo “Tier $val”,“teir”$val"count"," $result%"
val=$((val+1))
done

2 Likes

You can use eval to simplify nesting, and bc for greater control over the number of decimal places:

#!/bin/bash
TOTAL=99 
tier1count=11
tier2count=22
tier3count=67
for x in 1 2 3
do
  eval txc='$'tier"$x"count
  echo "Tier $x", $txc, `bc <<< "scale=3;100*$txc/$TOTAL"`'%'
done

Outputs:

Tier 1, 11, 11.111%
Tier 2, 22, 22.222%
Tier 3, 67, 67.676%
2 Likes

thanks, I was trying to figure out how to use eval… but I couldnt get it working the way I was trying it.

1 Like

I edited my previous response to make use of a “here string”, so instead of this:

echo "Tier $x", $txc, `echo "scale=3;100*$txc/$TOTAL"|bc -l`'%'

You can just write this:

echo "Tier $x", $txc, `bc <<< "scale=3;100*$txc/$TOTAL"`'%'

Makes it a tad easier to read, and eliminates the double-echo (which might be confusing).

Here strings (the shorter version of here docs) can come in handy for other things as well — not just eliminating echoes.

this is soo cool, i didnt know you could break a var apart like that … and smash another var in it… and roll over it… this thing is crazy

1 Like

Yes indeed. :slight_smile: But with great power comes great responsibility… You probably wouldn’t want to eval any dynamic variable that could ever contain arbitrary, user-supplied text in it — or you may as well kiss security goodbye.