I am trying to divide two values in a loop using bc, and I have set that value as a variable. My problem is that I want that value to have 2 decimal places, but I am having trouble getting scale=2 to work while defined inside a variable.

Here is my test file:

cat file.txt
Sc0000000_hap1  0   1200    32939
Sc0000000_hap1  1199    2388    28521
Sc0000001_hap1  0   1200    540

Here is the loop I am running:

while read name start stop sum; do

   divisor=`expr ${stop} - ${start}`
   avg=`scale=2; expr $sum / $divisor | bc ` #I want 2 decimal points here
   echo ${name} ${start} ${stop} ${avg} >> ${outfile}

done < file.txt

Here is the output I am getting:

Sc0000000_hap1 0 1200 27
Sc0000000_hap1 1199 2388 23
Sc0000001_hap1 0 1200 0

Here is the output I want:

Sc0000000_hap1 0 1200 27.45
Sc0000000_hap1 1199 2388 23.99
Sc0000001_hap1 0 1200 0.43

I have tried a few variations on my syntax but I can't seem to get it to work. Can someone show me how to code this correctly? Thanks in advance.

1 Answer 1

   avg=`scale=2; expr $sum / $divisor | bc `

You are

  • setting a shell variable scale to 2
  • calculating the integer division using expr and passing that value to bc (read man expr)
  • bc does not perform any calculations, it just outputs the number that was fed into it.

Let bc do the work:

avg=$(echo "scale=2; $sum / ($stop - $start)" | bc)

Now bc gets to do the whole calculation, and you set the bc scale variable.

Braces are not the same as double quotes. Use:

   echo "${name} ${start} ${stop} ${avg}" >> ${outfile}

Use $(...) instead of `...`

  • Yes this works perfectly. Thank you for your clarification on this!
    – mdem7705
    Jul 21, 2020 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.