我想将浮点变量与整数进行比较。 我知道这不是最好用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
如果我尝试使用test = 0.43,则第一个循环甚至不起作用。我认为这与整数和浮点比较有关,但无法使其有效。
我缺少什么?
PS:这个[0.43: command not found
是终端输出的内容。
答案 0 :(得分:44)
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
如果关系为假,则关系表达式求值为0;如果关系为真,则关系表达式求值为1 [source]。但请注意,这是GNU bc
的行为,并且它不是POSIX
条件。
答案 1 :(得分:10)
有点老问题,但我认为还有一个额外的答案。
虽然管道到更高精度的计算器(bc或dc)工作,但它是以叉子和额外过程为代价的,因为这些计算器不是内置于bash中的。但是,内置的一件事是printf
。因此,如果您可以处理特定小数位数内的数字,您可以&#34;假&#34;浮点比较,具有如下函数:
#!/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
这里要考虑的一些事情。
[[[
命名为可爱。您可以随意命名。 ntest
或mynumericcomparison
甚至[[[
。printf
是bash中的一个内部功能,所以尽管它在你的道路上,但它并不需要花费一分钱。printf
格式。10#
语句中每个变量开头的case
强制比较发生在基数10,因为零填充数字可能会被解释为八进制。