bash中与变量的浮点比较

时间:2013-03-05 13:06:43

标签: 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 "output"

    elif ["$test" -gt $k]
    then echo "output$k"
    fi
done

如果我尝试使用test = 0.43,则第一个循环甚至不起作用。我认为这与整数和浮点比较有关,但无法使其有效。

我缺少什么?

PS:这个[0.43: command not found是终端输出的内容。

2 个答案:

答案 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

这里要考虑的一些事情。

  • 我将函数[[[命名为可爱。您可以随意命名。 ntestmynumericcomparison甚至[[[
  • printf是bash中的一个内部功能,所以尽管它在你的道路上,但它并不需要花费一分钱。
  • 目前,该功能支持最高999.999的数字。如果您需要更高的数字(或更高精度),请调整printf格式。
  • 10#语句中每个变量开头的case强制比较发生在基数10,因为零填充数字可能会被解释为八进制。

另请参阅:http://mywiki.wooledge.org/BashFAQ/022