bash中带变量的浮点比较
我想将浮点变量与整数进行比较。 我知道这不是用bash最好的方法,但我的整个脚本都是用bash编写的。 $number可以是任何整数。如果它小于或等于50,我想要output1,对于所有其他变量,我想要另一个变量k的输出。这就是我到目前为止所做的:bash中带变量的浮点比较,bash,if-statement,floating-point,Bash,If Statement,Floating Point,我想将浮点变量与整数进行比较。 我知道这不是用bash最好的方法,但我的整个脚本都是用bash编写的。 $number可以是任何整数。如果它小于或等于50,我想要output1,对于所有其他变量,我想要另一个变量k的输出。这就是我到目前为止所做的: number=43 test=$(echo "scale=2; $number/50" | bc -l) echo "$test" for k in {1..5} do if ["$test" -le 1] then echo "ou
number=43
test=$(echo "scale=2; $number/50" | bc -l)
echo "$test"
for k in {1..5}
do
if ["$test" -le 1]
then echo "output"
elif ["$test" -gt $k]
then echo "output$k"
fi
done
如果我尝试使用test=0.43,则第一个循环甚至不起作用。我认为它与整数和浮点比较有关,但不能使它工作
我遗漏了什么
PS:this
[0.43:command not found
是终端输出的。Bash无法处理浮动。改为管道到bc
:
if [ $(echo " $test > $k" | bc) -eq 1 ]
您看到的错误是因为test
命令(即[
)前后需要空格
使用(…)
更好,因为您可以这样比较数字:
if (( $(bc <<< "$test > $k") ))
if (( $(bc <<< "$test <= 1") ))
then
echo "output"
elif (( $(bc <<< "$test > $k") ))
then
echo "output$k"
fi
#!/usr/bin/env bash
function [[[ () {
local LANG=C lhs rhs
printf -v lhs '%07.3f' "$1"; lhs=${lhs/./}
printf -v rhs '%07.3f' "$3"; rhs=${rhs/./}
case "$2" in
-lt) return $(( ! ( 10#$lhs < 10#$rhs ) )) ;;
-le) return $(( ! ( 10#$lhs <= 10#$rhs ) )) ;;
-eq) return $(( ! ( 10#$lhs == 10#$rhs ) )) ;;
-ge) return $(( ! ( 10#$lhs >= 10#$rhs ) )) ;;
-gt) return $(( ! ( 10#$lhs > 10#$rhs ) )) ;;
esac
}
number=${1:-43}
test=$(dc -e "2k $number 50 / p")
echo "$test"
for k in {1..5}; do
if [[[ "$test" -le 1 ]]]; then
echo "output"
elif [[[ "$test" -gt "$k" ]]]; then
echo "output $k"
fi
done
if($(bc这是一个老问题,但我认为它还有一个额外的答案
当管道连接到一个更高精度的计算器(bc或dc)时,它是以一个叉子和一个额外的过程为代价的,因为这些计算器不是bash内置的。但是,内置的一件事是printf
。因此,如果你能处理在特定小数位数内的数字,你可以“伪造”浮点比较,使用如下函数:
if (( $(bc <<< "$test > $k") ))
if (( $(bc <<< "$test <= 1") ))
then
echo "output"
elif (( $(bc <<< "$test > $k") ))
then
echo "output$k"
fi
#!/usr/bin/env bash
function [[[ () {
local LANG=C lhs rhs
printf -v lhs '%07.3f' "$1"; lhs=${lhs/./}
printf -v rhs '%07.3f' "$3"; rhs=${rhs/./}
case "$2" in
-lt) return $(( ! ( 10#$lhs < 10#$rhs ) )) ;;
-le) return $(( ! ( 10#$lhs <= 10#$rhs ) )) ;;
-eq) return $(( ! ( 10#$lhs == 10#$rhs ) )) ;;
-ge) return $(( ! ( 10#$lhs >= 10#$rhs ) )) ;;
-gt) return $(( ! ( 10#$lhs > 10#$rhs ) )) ;;
esac
}
number=${1:-43}
test=$(dc -e "2k $number 50 / p")
echo "$test"
for k in {1..5}; do
if [[[ "$test" -le 1 ]]]; then
echo "output"
elif [[[ "$test" -gt "$k" ]]]; then
echo "output $k"
fi
done
!/usr/bin/env bash
函数[[(){
本地语言=C lhs rhs
printf-v lhs'%07.3f'$1;lhs=${lhs/}
printf-v rhs'%07.3f'$3;rhs=${rhs/}
案件“$2”
-lt)返回$(!(10#$lhs<10#$rhs));;
-le)返回$(!(10#$lhs=10#$rhs));;
-gt)返回$(!(10#$lhs>10#$rhs));;
以撒
}
数字=${1:-43}
测试=$(dc-e“2k$数字50/p”)
回显“$test”
对于{1..5}中的k;do
如果[[“$test”-le 1]];则
回声“输出”
elif[[“$test”-gt“$k”]];然后
回显“输出$k”
fi
完成
这里需要考虑的一些事情。
- 我把这个函数命名为
[[[/code>,你可以随意命名。ntest
或mynumericcomparison
甚至[[[/code>
printf
是bash中的一个内部函数,因此尽管它在您的路径上,但它不需要花费一个fork
- 目前,该函数最多支持999.999的数字。如果需要更高的数字(或更高的精度),请调整
printf
格式
case
语句中每个变量开头的10
将强制比较以10为基数,因为零填充的数字可能会被解释为八进制
另请参见:另请参见:bash:[:1.3:如果已正确格式化[]表达式,则预期的整数表达式将是错误的+1@user000001Great谢谢!很有效。我正在研究一个小问题。我希望第一个if小于或等于1,而另一个则严格高于k。我可以写(($(bc)第二个是正确的。第一个是正确的,如果你这样引用:($(bc将&&
更改为|
,在我之前的评论中,谢谢你,它工作得很好。这看起来很好,但为了便于复制粘贴,我将printf
格式设置为更合理的格式(浮动可能相当长,保持较低的精度不会使此功能更快)。您也可以切换到ksh并使用排版自动取整。(从1993年开始提供,效果很好)