0

I am trying to multiply array values with values derived from the multiplication of a loop index using bc.

#!/bin/bash n=10.0 bw=(1e-3 2.5e-4 1.11e-4 6.25e-5 4.0e-5 2.78e-5 2.04e-5 1.56e-5 1.29e-5 1.23e-5 1.0e-5) for k in {1..11};do a=$(echo "$n * $k" | bc) echo "A is $a" arn=${bw[k-1]} echo "Arn is $arn" b=$(echo "$arn * $a" | bc -l) echo "b is $b" #echo $a $b done 

I am able to echo the array values by assigning it to a new variable within the loop, but when I use that to multiply using bc, I get (standard_in) 1: syntax error. I searched for clues and tried some but none helped. The expected output is as follows.

10 1.00E-02 20 5.00E-03 30 3.33E-03 40 2.50E-03 50 2.00E-03 60 1.67E-03 70 1.43E-03 80 1.25E-03 90 1.16E-03 100 1.23E-03 110 1.10E-03 

All help is greatly appreciated.

0

    3 Answers 3

    3

    Replacing OP's for loop with a single awk script:

    awk -v n="$n" ' # assign awk variable "n" the value of OS variable "n" { k++ # increment counter (initially == 0) printf "%s %0.2E\n",(k*n),($1*k*n) # print output } ' < <(printf "%s\n" "${bw[@]}") # print each bw[] entry on a separate line 

    This generates:

    10 1.00E-02 20 5.00E-03 30 3.33E-03 40 2.50E-03 50 2.00E-03 60 1.67E-03 70 1.43E-03 80 1.25E-03 90 1.16E-03 100 1.23E-03 110 1.10E-03 
      2

      bc doesn't support scientific notation, but you could replace e with *10^ to get the result.

      $ printf 'print k+=10, " ", k*%s, "\n"\n' "${bw[@]/[eE]/*10^}" | bc -l 10 .01000000000000000000 20 .00500000000000000000 30 .00333000000000000000 40 .00250000000000000000 50 .00200000000000000000 60 .00166800000000000000 70 .00142800000000000000 80 .00124800000000000000 90 .00116100000000000000 100 .00123000000000000000 110 .00110000000000000000 

      (here assuming GNU bc for its print extension).

      If the point of using bc is that you want arbitrary precision, you could use perl's bignum module for that:

      $ perl -Mbignum -e 'for $i (@ARGV) {printf "%-3d %.2E\n", $k += 10, $i * $k}' -- "${bw[@]}" 10 1.00E-02 20 5.00E-03 30 3.33E-03 40 2.50E-03 50 2.00E-03 60 1.67E-03 70 1.43E-03 80 1.25E-03 90 1.16E-03 100 1.23E-03 110 1.10E-03 

      If you don't need arbitrary precision, then it would be easier to switch to a shell with floating point support like zsh, ksh93 or yash.

      A lot of the syntax in that script such as array=(...) or {1..11} actually come from zsh, borrowed by bash years later.

      #! /bin/zsh - bw=( 1e-3 2.5e-4 1.11e-4 6.25e-5 4.0e-5 2.78e-5 2.04e-5 1.56e-5 1.29e-5 1.23e-5 1.0e-5 ) k=0 for i ($bw) printf '%-3d %.2E\n' k+=10 'k*i' 
        1

        bc doesn't support the scientific format. Use something that does.

        For example, Perl:

         a=$(perl -e "print $n * $k" ) arn=${bw[k-1]} b=$(perl -e "printf '%.2E', $arn * $a") echo $a $b 

        Output:

        10 1.00E-02 20 5.00E-03 30 3.33E-03 40 2.50E-03 50 2.00E-03 60 1.67E-03 70 1.43E-03 80 1.25E-03 90 1.16E-03 100 1.23E-03 110 1.10E-03 

          You must log in to answer this question.

          Start asking to get answers

          Find the answer to your question by asking.

          Ask question

          Explore related questions

          See similar questions with these tags.