在与this question相同的帖子中,我正在给出另一个镜头并请求SO帮助解决我应该如何解决这个问题。我正在编写一个bash脚本,需要执行以下操作:
x
和y
中有一个半径为r
的圈子。resolution
,这是我正在检查的点之间的距离。i
和j
i
和j
需要从-r/resolution
转到+r/resolution
。echo "some_text i*resolution j*resolution 15.95 cm"
(注意缺少$
因为我无能为力)。这个输出就是我真正想要的。到目前为止我最好的拍摄:
r=40.5
resolution=2.5
end=$(echo "scale=0;$r/$resolution") | bc
for (( i=-end; i<=end; i++ ));do
for (( j=-end; j<=end; j++ ));do
x=$(echo "scale=5;$i*$resolution") | bc
y=$(echo "scale=5;$j*$resolution") | bc
if (( x*x + y*y <= r*r ));then <-- No, r*r will not work
echo "some_text i*resolution j*resolution 15.95 cm"
fi
done
done
我对bash已经足够了,可能会像我上一个问题中某人所建议的那样查看ksh,但是如果有人知道执行此操作的正确方法,请告诉我!无论如何解决这个问题,它都将确定我未来的气质,以确保打击bash脚本。
答案 0 :(得分:1)
您可能希望将管道包含在$()中的bc中。而不是。
end=$(echo "scale=0;$r/$resolution") | bc
使用
end=$(echo "scale=0;$r/$resolution" | bc)
应该有所帮助。
编辑这是一个解决方案。
r=40.5
resolution=2.5
end=$(echo "scale=0;$r/$resolution" | bc)
for i in $(seq -${end} ${end}); do
for j in $(seq -${end} ${end}); do
x=$(echo "scale=5;$i*$resolution" | bc)
y=$(echo "scale=5;$j*$resolution" | bc)
check=$(echo "($x^2+$y^2)<=$r^2" | bc)
if [ ${check} -eq '1' ]; then
iRes=$(echo "$i*$resolution" | bc)
jRes=$(echo "$j*$resolution" | bc)
echo "some_text $iRes $jRes 15.95 cm"
fi
done
done
答案 1 :(得分:1)
如前所述,使用bc,awk,ksh或其他脚本语言可能最好解决这个问题。
Pure Bash。实际上需要浮点运算的简单问题有时可以仅使用整数转换为某种定点运算。以下解决方案模拟小数点后的2位小数。 如果这个精度足够的话,循环内部就不需要管道和外部过程。
factor=100 # 2 digits after the decimal point
r=4050 # the representation of 40.50
resolution=250 # the representation of 2.50
end=$(( (r/resolution)*factor )) # correct the result of the division
for (( i=-end; i<=end; i+=factor )); do
for (( j=-end; j<=end; j+=factor )); do
x=$(( (i*resolution)/factor )) # correct the result of the division
y=$(( (j*resolution)/factor )) # correct the result of the division
if [ $(( x*x + y*y )) -le $(( r*r )) ] ;then # no correction needed
echo "$x $y ... "
fi
done
done
echo -e "resolution = $((resolution/factor)).$((resolution%factor))"
echo -e "r = $((r/factor)).$((r%factor))"
答案 2 :(得分:0)
awk 'BEGIN{
r=40.5
resol=2.5
end = r/resol
print end
for (i=-end;i<=end;i++) {
for( j=-end;j<=end;j++ ){
x=sprintf("%.5d",i*resol)
y=sprintf("%.5d",j*resol)
if ( x*x + y*y <= r*r ){
print ".......blah blah ......"
}
}
}
}'
答案 3 :(得分:0)
它看起来更像是一个bc
脚本,而不是一个Bash,所以这里有:
#!/usr/bin/bc -q
/* -q suppresses a welcome banner - GNU extension? */
r = 40.5
resolution = 2.5
scale = 0
end = r / resolution
scale = 5
for ( i = -end; i <= end; i++ ) {
/* moved x outside the j loop since it only changes with i */
x = i * resolution
for ( j = -end; j <= end; j++ ) {
y = j * resolution
if ( x^2 * y^2 <= r^2 ) {
/*
the next few lines output on separate lines, the quote on
a line by itself causes a newline to be created in the output
numeric output includes newlines automatically
you can comment this out and uncomment the print statement
to use it which is a GNU extension
*/
/* */
"some_text
"
i * resolution
j * resolution
"15.95 cm
"
/* */
/* non-POSIX:
print "some_text ", i * resolution, " ", j * resolution, " 15.95 cm\n"
*/
}
}
}
quit