bash中带变量的浮点比较

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

我想将浮点变量与整数进行比较。 我知道这不是用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: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年开始提供,效果很好)