3개의 입력 매개변수를 허용하는 .c 프로그램("스위치")을 여러 번 실행하는 쉘 스크립트가 있습니다. 프로그램을 4번 실행하고 값 {4,16,32,64}
과 매개변수를 전달 {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
식별한 처음 두 줄은 명령을 실행하고 해당 출력을 캡처하기 위한 것입니다. 그래야 합니다. 수학적 표현을 평가하는 데 사용하는 것이 맞습니다.$((command))
$(command)
$((expression))
또한 제곱근선은 다음과 같아야 합니다.
dvt=$(echo "sqrt($dvt)" | bc -l)
대신에
dvt=$((echo `sqrt($dvt) | bc -l`))
심지어
dvt=$(echo `sqrt($dvt) | bc -l`)
이 명령의 문제점은 margen=
표현식의 용어 중 하나로 부동 소수점을 전달한다는 점일 수 있습니다.
답변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