BASH:百分比变化 - 如何计算?如何在没有 bc 的情况下获得绝对值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27267830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BASH: Percentage change - how to calculate it? How to get absolute value without bc?
提问by dziki
I need to count a percentage change between two values.
我需要计算两个值之间的百分比变化。
The code I have here:
我在这里的代码:
echo $time1
echo $time2
pc=$(( (($time2 - $time1)/$time1 * 100) ))
echo $pc
Brings such output in the console (with set -xe
option)
在控制台中带来这样的输出(带set -xe
选项)
+ echo 1800
1800
+ echo 1000
1000
+ pc=0
+ echo 0
The code inside the math expression seems to be written properly, still, I get -80 or so. Why is this happening to me?
数学表达式中的代码似乎写得正确,但我仍然得到 -80 左右。为什么这会发生在我身上?
The second part of the question. I have no access and I will have no access to the bc command. From what I heard it can give me the absolute value of the number I have.
问题的第二部分。我没有访问权限,也无法访问 bc 命令。据我所知,它可以给我所拥有数字的绝对值。
So.. Without the bc command - will this be a good idea for an IF condition?
所以..如果没有 bc 命令 - 这对于 IF 条件是一个好主意吗?
if (( (( "$pc" > 20 || (( "$pc" < -20 )); then...
回答by Tom Fenech
As you have mentioned that it's not necessary to do this in bash, I would recommend using awk:
正如您所提到的,没有必要在 bash 中执行此操作,我建议使用 awk:
awk -v t1="$time1" -v t2="$time2" 'BEGIN{print (t2-t1)/t1 * 100}'
Normally, awk is designed to process files but you can use the BEGIN
block to perform calculations without needing to pass any files to it. Shell variables can be passed to it using the -v
switch.
通常,awk 旨在处理文件,但您可以使用该BEGIN
块执行计算,而无需向其传递任何文件。可以使用-v
开关将外壳变量传递给它。
If you would like the result to be rounded, you can always use printf
:
如果您希望结果四舍五入,您可以随时使用printf
:
awk -v t1="$time1" -v t2="$time2" 'BEGIN{printf "%.0f", (t2-t1)/t1 * 100}'
The %.0f
format specifier causes the result to be rounded to an integer (floating point with 0 decimal places).
的%.0f
说明符将导致结果格式被舍入为整数(浮点0小数位)。
回答by mirabilos
回答by mboyar
Maybe you want to prefer bc+awk mixed line, something like this:
也许你想更喜欢 bc+awk 混合线,像这样:
total=70
item=30
percent=$(echo %$(echo "scale = 2; ($item / $total)" | bc -l | awk -F '.' '{print }'))
echo $percent
回答by Stephen Quan
Some notes:
一些注意事项:
- The math is integer based, so you're getting zero early because you divide
- The
$(( ))
syntax will expand variables so usetime1
instead of$time1
- The percentage answer is -44 not -80
- 数学是基于整数的,所以你很早就得到零,因为你除
- 该
$(( ))
语法将扩大变量,这样使用time1
的,而不是$time1
- 百分比答案是 -44 而不是 -80
Here are some examples:
这里有些例子:
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