이 문제를 해결하기 위해 다양한 방법을 시도했지만 해결책을 찾을 수 없기 때문에 이 질문이 중복되지 않기를 바랍니다.
매 라운드마다 이름이 변경되는 변수에 명령 출력을 저장하고 에코하고 다음과 같이 이러한 변수에 대해 추가로 작업하려는 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 ...
임의의 네트워크 크기에 대한 두 번째 문제를 어떻게 해결합니까?
답변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)
반복할 때마다 한 번만 수행하는 것은 낭비입니다.