bcを使用したbash配列の乗算

bcを使用したbash配列の乗算

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

ループ内の新しい変数に代入して配列値をエコーすることができますが、それを乗算するために使用するbc(standard_in) 1: syntax error。私は手がかりを探していくつか試しましたが、何も役に立ちませんでした。予想される出力は次のとおりです。

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

すべての助けに感謝します。

答え1

forOPのループを単一のスクリプトに置き換えますawk

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

これで以下が生成されます。

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科学的表記法はサポートされていませんが、結果を得るeために置き換えることができます。*10^

$ 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

(これは拡張子がGNUであると仮定しますbcprint

使用目的がbc任意の精度を望む場合perlbignumモジュールを使用できます。

$ 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

任意の精度が必要ない場合は、浮動小数点をサポートするシェル(例:zsh、ksh93、yash)に切り替えるのが簡単です。

array=(...)たとえば、実際にzshからインポートされたこのスクリプトの構文の多くは、{1..11}数年後にbashから借用されました。

#! /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'

答え3

bcエンジニアリング形式はサポートされていません。そうすることを使用しなさい。

たとえば、Perlは次のようになります。

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

出力:

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

関連情報