BASH:百分比变化 - 如何计算?如何在没有bc的情况下获得绝对价值?

时间:2014-12-03 09:23:19

标签: bash math arithmetic-expressions

我需要计算两个值之间的百分比变化。

我在这里的代码:

echo $time1
echo $time2
pc=$(( (($time2 - $time1)/$time1 * 100) ))
echo $pc

在控制台中输入此类输出(使用set -xe选项)

+ echo 1800
1800
+ echo 1000
1000
+ pc=0
+ echo 0

数学表达式中的代码似乎写得正确,但是,我得到-80左右。为什么会发生这种情况?

问题的第二部分。我没有访问权限,我将无法访问bc命令。据我所知,它可以给我数字的绝对值。

所以..没有bc命令 - 这对于IF条件是个好主意吗?

if (( (( "$pc" > 20 || (( "$pc" < -20 )); then...

4 个答案:

答案 0 :(得分:4)

正如你提到的那样,没有必要在bash中这样做,我建议使用awk:

awk -v t1="$time1" -v t2="$time2" 'BEGIN{print (t2-t1)/t1 * 100}'

通常,awk旨在处理文件,但您可以使用BEGIN块来执行计算,而无需将任何文件传递给它。可以使用-v开关将Shell变量传递给它。

如果您希望对结果进行舍入,则可以始终使用printf

awk -v t1="$time1" -v t2="$time2" 'BEGIN{printf "%.0f", (t2-t1)/t1 * 100}'

%.0f格式说明符会将结果舍入为整数(浮点数为0位小数)。

答案 1 :(得分:1)

正确的舍入,nicer空格,没有多余的$符号:

pc=$(( ((((time2 - time1) * 1000) / time1) + (time2 > time1 ? 5 : -5)) / 10 ))

答案 2 :(得分:1)

也许你想要更喜欢bc + awk混合线,如下所示:

total=70
item=30
percent=$(echo %$(echo "scale = 2; ($item / $total)" | bc -l | awk -F '.' '{print $2}'))
echo $percent

答案 3 :(得分:1)

一些注意事项:

  • 数学是基于整数的,所以你因为划分
  • 而提前得到零
  • $(( ))语法会扩展变量,因此请使用time1代替$time1
  • 答案百分比是-44而不是-80

以下是一些例子:

echo $(( time2-time1 )) # Output: -800
echo $(( (time2-time1)/time1 )) # Output: 0. see it's already zero!
echo $(( (time2-time1)/time1*100 )) # Output: 0. it's still zero and still 'incorrect'
echo $(( (time2-time1)*100 )) # Output: -80000. fix by multiplying before dividing
echo $(( (time2-time1)*100/time1 )) # Output: -44. this is the 'correct' answer
echo $(( (time2-time1)*100/time2 )) # Output: -80. note this is also an 'incorrect' answer