{4,16,32,64}
3 つの入力パラメータを受け入れる .c プログラム ('switch') を複数回実行するシェル スクリプトがあります。値を渡し、パラメータに対して プログラムを 4 回実行して{0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
、平均と信頼区間の表を作成します。スクリプトは次のとおりです。
#!/bin/bash
if [ -e salida.txt ]; then
# echo "File exists"
rm salida.txt
fi
touch salida.txt
touch sal1.txt
touch sal2.txt
touch sal3.txt
touch sal4.txt
touch salida.txt
num=1000000
stud=3.182
for j in {0.1,0.2,.3,.4,.5,.55,.575,.6,.625,.65,.7,.75,.8,.9}
do
rm sal1.txt sal2.txt sal3.txt sal4.txt
for i in {4,16,32,64}
do
margen=0
sum=0
avg=0
for k in {1..4}
do
a$k=$((`./switch -N$i -r$j -n$num`))
sum=$((sum + a$k))
done
avg=$((sum/4))
dvt=0
for k in {1..4}
do
dvt=$((dvt + (a$k - $avg)*(a$k - $avg)))
done
dvt=$((dvt /3))
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
echo $avg $margen >> sal$i.txt
done
join sal1.txt sal2.txt sal3.txt sal4.txt >> salida.txt
done
それにもかかわらず、27行目でエラーが発生します
a$k=$((`./switch -N$i -r$j -n$num`))
と線
dvt=$((echo `sqrt($dvt) | bc -l`))
margen=$((dvt*$stud/2))
何が間違っているのでしょうか?
答え1
最初に特定した 2 行は、 コマンドを実行してその出力をキャプチャするために を使用しています。 これは のはずです。 数式を評価するためにを使用するのは正しいです。$((command))
$(command)
$((expression))
また、平方根線は
dvt=$(echo "sqrt($dvt)" | bc -l)
それよりも
dvt=$((echo `sqrt($dvt) | bc -l`))
あるいは
dvt=$(echo `sqrt($dvt) | bc -l`)
コマンドの問題は、margen=
式の項の 1 つとして float を渡していることにある可能性があります。
答え2
の設定をa$k
次のような連想配列に再構成します。
declare -a a
for k in {1..4}
do
a[$k]=$((`./switch -N$i -r$j -n$num`))
sum=$((sum + a[$k]))
done
a
これにより、上記のループから値が入力された後、for
コードのさらに下にある他のループから配列にアクセスできるようになります。
最後のループのさらに下にあるこの行for
も、次のように調整する必要があります。
dvt=$((dvt + (a[$k] - $avg)*(a[$k] - $avg)))
$((..)) を含む浮動小数点数
この表記法を使用して浮動小数点数を追加できるとは思えません$((...))
。少なくとも私が試したときは、うまくいきませんでした。
$ echo $((0.10 + .20))
bash: 0.10 + .20: syntax error: invalid arithmetic operator (error token is ".10 + .20")
bc
浮動小数点数をトークンとして使用してこれらの操作を実行するには、 またはこれらの操作を実行できる計算機を使用する必要があります。
$ echo "0.10 + .20" | bc
.30