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

BASH:百分比变化-如何计算?如何在没有bc的情况下获得绝对值?,bash,math,arithmetic-expressions,Bash,Math,Arithmetic Expressions,我需要计算两个值之间的百分比变化 我这里的代码是: echo $time1 echo $time2 pc=$(( (($time2 - $time1)/$time1 * 100) )) echo $pc 将此类输出带到控制台中(使用set-xe选项) 数学表达式中的代码似乎写得很好,但我还是得到了-80左右。为什么这会发生在我身上 问题的第二部分。我没有访问权限,也将没有访问bc命令的权限。从我所听到的,它可以给我的数字的绝对值 所以。。如果没有bc命令,这对IF条件是个好主意吗 if ((

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

我这里的代码是:

echo $time1
echo $time2
pc=$(( (($time2 - $time1)/$time1 * 100) ))
echo $pc
将此类输出带到控制台中(使用
set-xe
选项)

数学表达式中的代码似乎写得很好,但我还是得到了-80左右。为什么这会发生在我身上

问题的第二部分。我没有访问权限,也将没有访问bc命令的权限。从我所听到的,它可以给我的数字的绝对值

所以。。如果没有bc命令,这对IF条件是个好主意吗

if (( (( "$pc" > 20 || (( "$pc" < -20 )); then...
如果(((“$pc”>20 | |)((“$pc”<-20)),那么。。。

正如您提到的,在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位的浮点)。

具有正确的四舍五入、空格,并且没有冗余的
$
符号:

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

也许你更喜欢bc+awk混合线,比如:

total=70
item=30
percent=$(echo %$(echo "scale = 2; ($item / $total)" | bc -l | awk -F '.' '{print $2}'))
echo $percent
一些注意事项:

  • 数学是基于整数的,所以你很早就得到了零,因为你要除法
  • $(())
    语法将展开变量,因此使用
    time1
    而不是
    $time1
  • 答案是-44而不是-80
以下是一些例子:

echo$((time2-time1))#输出:-800
echo$((time2-time1)/time1))#输出:0。请看它已经为零了!
echo$((time2-time1)/time1*100))#输出:0。它仍然为零并且仍然“不正确”
echo$((time2-time1)*100))#输出:-80000。通过除法前的乘法进行修正
echo$((time2-time1)*100/time1))#输出:-44。这是“正确”的答案
echo$((time2-time1)*100/time2))#输出:-80。请注意,这也是一个“不正确”的答案
简言之,正确的答案是:

time1=1800
时间2=1000
pc=$((时间2-时间1)*100/时间1))#-44
请注意,
符号
也可用于处理表达式和赋值

time1=1800
时间2=1000
((pc=((时间2-时间1)*100/时间1))#-44

Bash只进行整数运算,因此如果
$time2-$time1
小于
$time1
,则除法将始终为零。但是,如果稍微重新排序表达式,如在除法之前进行乘法,结果应该会更好一些。是否要求在纯Bash中进行此操作?@TomFenech,不,可以这样做在任何适合我的工具中都可以使用。例如,可以用perl来完成。你看了答案了吗?你需要任何额外的澄清吗?取决于首先如何获得值以及条件代码应该做什么,你可能可以在awk中完成整件事。这是一个很好的解决方案,并且更新它,不,我将它标记为一个解决方案,但我需要保护自己不受某些情况的影响,所以我目前正在编写一个perl脚本。不过,感谢您的回答!没问题。对于涉及shell变量的快速浮点计算,awk可能很有用,但它有点滥用
开始
块,因此对于更复杂的hings,Perl可能是一个更好的选择。另一方面,如果这两个变量实际上是从一个文件中读取的,那么使用awk可能是最好的解决方案。@TomFenech我正在寻找一种计算百分比变化的方法。这并不真的重要-一个舍入值正在起作用。好的,使用
bc
或其他方法可以更精确如果没有
bc
,我的脚本99%是用bash编写的,因此我需要一个与bash兼容的输出。在本例中,如果100*(time1-time2)可能超过max int,则-integer:)很有用。
total=70
item=30
percent=$(echo %$(echo "scale = 2; ($item / $total)" | bc -l | awk -F '.' '{print $2}'))
echo $percent