与bash中的variables浮点比较
我想比较一个浮点variables到一个整数。 我知道这不是最好的与bash,但我的整个脚本已经写在bash中。 $数字可以是任何整数。 如果它低于或等于50,我想输出1,对于所有其他我想用另一个variablesk输出。 这是我迄今为止:
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
如果我尝试testing= 0.43,第一个循环甚至不工作。 我认为它必须做一个整数和浮点比较,但不能使其工作。
我错过了什么?
PS:这个[0.43: command not found
是terminal输出的。
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
如果关系为假,则关系expression式计算为0;如果关系为真,则关系expression式计算为[ source ]。 但请注意,这是GNU bc
的行为,并不是POSIX
compiant。
这是一个古老的问题,但我认为还有额外的答案。
虽然pipe道到更高精度的计算器(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
这里有几件事要考虑。
- 我已经命名了
[[[
很可爱。 你可以任意命名。mynumericcomparison
或mynumericcomparison
甚至[[[
。 -
printf
是bash中的一个内部函数,所以尽pipe事实上它在你的path上,但它并不花费一个分支。 - 就目前而言,该function支持最高999.999的数字。 如果您需要更高的数字(或更高精度),请调整
printf
格式。 -
case
语句内每个variables的开始处的10#
是强制比较发生在base 10,因为零填充的数字可能被解释为八进制数。
另见: http : //mywiki.wooledge.org/BashFAQ/022