この問題を解決するためにさまざまな方法を試しましたが、解決策が見つからないため、この質問が重複しないことを願っています。
各ラウンドごとに名前が変更された変数にコマンド出力を保存してエコーし、これらの変数に対して次のようにさらに作業したいforループがあります。
for i in `seq 1 $netsize`
do
echo "node$i: "
export Bal$i=$(node$i getbalance | bc) #PIPE TO BC SINCE getbalance RETURNS FLOAT TYPE VALUE
echo $Bal$i | tee -a <text-file path> #THIS GIVES ME ONLY 1,2,... NOT THE getbalance VALUE!!!
...
また、node1のgetbalanceを取得し、すべてのノードの合計残高の合計に分割したいと思います。だからこれをしましたが、構文エラーが発生しました。
...
echo "$Bal1/($Bal1+$Bal2+$Bal3+$Bal4+$Bal5+$Bal6+$Bal7+$Bal8+$Bal9)" | bc >> <text-file path> #HERE; I DO THIS FOR A netsize OF 9 NODES ...
任意のネットワークサイズに関する2番目の問題をどのように解決しますか?
答え1
bash配列を使用してこれを行うことができます。この値を次のようにインデックス配列に格納します。
declare -a bal
for i in `seq 1 $netsize`
do
echo "node$i: "
bal[$i]=$(node$i getbalance | bc) //PIPE TO BC SINCE getbalance RETURNS FLOAT TYPE VALUE
echo ${bal[$i]} # should be the right value
done
その後、エコーしたいコマンドを組み合わせると、bc
サブシェルなどを使って小さなIFS
ゲームをすることになります。
denominator=$(IFS=+; echo "${bal[*]:2}")
equation="${bal[1]}/($denominator)"
設定すると、次のステートメントでそのフィールドをエコーすると、配列内のIFS=+
フィールドが分離されます。配列のすべての要素(たとえば、一部)に+
アクセスします。ただし、この場合、要素番号1が方程式の分子に使用されるため、スキップしたい要素であることがわかっているので、indexから始まる要素を追加します。したがって、配列インデックス2以上ですべての要素が取得されます。${bal[*]:2}
bal
${bal[*]}
:2
2
${bal[*]:2}
bal
答え2
netsize=$somenum
( echo scale=\(2; set -- ### set scale; clear args
while [ "$#" -lt "$netsize" ] ### counts up to $netsize
do set "$@" "bal$(($#+1))" ### saves arg count as bal$#+1
### I do the below because you don't say what
### node$# getbalance does. Here it's random.
eval "node$#(){ "':& x=${!%??} y=${!#"$x"}
echo "$x.$y/'"$#\"; }" ### fakes a node$#() function
printf "%bbal$#=%b" ');"' '";' \( ### );"bal$#=";(bal$#=
"node$#" getbalance ### $x.$y/$#\n
done; printf %b+ ");($1/($@))\c" ### );(bal1/(bal1+...bal$netsize))
) | paste -sd\\0 | bc ### removes all \newlines but last
だから何をしたいのかを言うのは簡単ではbc
ありません。その逆は、はるかに便利な方法、つまりbc
それ自体が完全なスクリプト言語である対話型プログラムです。通常の実行時間中に変数の値を設定して保存するので、これらすべての情報をシェルに保存するのではなく、方程式を出力してそのbc
値を保存します。
たとえば、
{ echo 'x=1+2'; echo '"x=";x'; }| bc
...印刷...
x=3
最初に同等とbc
評価してから、ランダムな文字列をstdoutに印刷し、最後に値を印刷するように求められます。x
1+2
"x="
x
上記のスクリプトは実際に同じことを行います。各反復はbal
1ずつ増加します。それは印刷されますbc
:
);"bal$#=";(bal$#=$!/$#\n
...そして$#
一致するように増加すると$netsize
印刷されます。(10を例に挙げます$netsize
。)...
(bal1/(bal1+bal2+bal3+bal4+bal5+bal6+bal7+bal8+bal9+bal10))
この値はシェルにまったく保存されませんが、bc
記憶されます。bc
式を(
括弧で囲むと)
評価されます。そして印刷。
私はそれが何をすべきかわからないので、paste -sd\\0
すべてのewlineを削除しようとしましたが、出力の後にewlineが追加されると仮定します。\n
"node$#" getbalance
\n
(bal1=
node$# getbalance's output
\n)
文法エラーです。だからすべて消去し、;
セミコロンで表現を区別しました。node$# getbalance
(むしろ文字が印刷されないことを願っています)。スクリプト全体が印刷する内容について明確なアイデアを得るには、末尾のbc
エントリをw /に置き換えることができますtr \; \\n
。
たとえば、次の条件が満たされると印刷されますnetsize=10
。
scale=(2)
"bal1="
(bal1=261.40/1)
"bal2="
(bal2=261.41/2)
"bal3="
(bal3=261.42/3)
"bal4="
(bal4=261.44/4)
"bal5="
(bal5=261.45/5)
"bal6="
(bal6=261.46/6)
"bal7="
(bal7=261.48/7)
"bal8="
(bal8=261.49/8)
"bal9="
(bal9=261.52/9)
"bal10="
(bal10=261.54/10)
(bal1/(bal1+bal2+bal3+bal4+bal5+bal6+bal7+bal8+bal9+bal10))
これらの内容はすべてbc
次のように印刷されます。
bal1=261.40
bal2=130.70
bal3=87.14
bal4=65.36
bal5=52.29
bal6=43.57
bal7=37.35
bal8=32.68
bal9=29.05
bal10=26.15
.34
入力と出力をより明確に理解できる場合は、必要に応じてより具体的に調整するのに役立ちますが、var=$(echo stuff at | bc)
繰り返すたびに一度だけ行うことは無駄です。