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