use*_*400 23 floating-point bash if-statement
我想将浮点变量与整数进行比较.我知道这不是最好用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 "output"
elif ["$test" -gt $k]
then echo "output$k"
fi
done
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用test = 0.43,则第一个循环甚至不起作用.我认为它与整数和浮点比较有关,但不能使它工作.
我错过了什么?
PS:这[0.43: command not found是终端输出的内容.
use*_*001 44
Bash无法处理浮动.管道bc改为:
if [ $(echo " $test > $k" | bc) -eq 1 ]
Run Code Online (Sandbox Code Playgroud)
您看到的错误是因为test命令(即[)之前和之后需要空格
使用它会更好,(( ... ))因为你比较这样的数字:
if (( $(bc <<< "$test > $k") ))
Run Code Online (Sandbox Code Playgroud)
循环中的部分应如下所示:
if (( $(bc <<< "$test <= 1") ))
then
echo "output"
elif (( $(bc <<< "$test > $k") ))
then
echo "output$k"
fi
Run Code Online (Sandbox Code Playgroud)
如果关系为假,则关系表达式求值为0;如果关系为真,则关系表达式求值为1 [ 源 ].但请注意,这是一种行为GNU bc,并不POSIX符合.
gho*_*oti 10
这是一个古老的问题,但我认为它还有一个额外的答案.
虽然管道到更高精度的计算器(bc或dc)工作,但它是以叉子和额外过程为代价的,因为这些计算器不是内置于bash中的.但是,内置的一件事是printf.因此,如果您可以处理特定小数位数内的数字,则可以使用如下函数"伪造"浮点比较:
#!/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
Run Code Online (Sandbox Code Playgroud)
这里要考虑几件事.
[[[为可爱.您可以随意命名.ntest或者mynumericcomparison甚至是[[[.printf 是bash中的一个内部函数,所以尽管它在你的路径上,它不需要一个分叉.printf格式.10#在内部的各个变量的开头case语句是迫使比较基部10发生的,因为零填充数字可能被解释为八进制.另见:http://mywiki.wooledge.org/BashFAQ/022