Linux中算数运算和bc命令
Linux中算数运算和bc命令
可以通过使用bash的let、(())、$(())或$[]
功能进行基本的整数运算,或者使用bc进行高级的运算。此外expr和awk等也能做基本数学运算。
其中let
和(())
等价,除了做数学运算,还支持数学表达式判断,例如数值变量a是否等于3:let a==3
或((a==3))
,但一般不会使用它们来判断,而是使用test命令结合条件表达式:test "$a" -eq 3
。因此,本文只介绍let的赋值运算功能。
通过shell进行整数运算
1 | [root@xuexi tmp]# str=10 |
let也可以使用(( ))
进行替换,它们等价。且额外的功能是:如果最后一个算术表达式结果为0,则返回状态码1,其余时候返回状态码0。
如果想在命令行中做计算,则可以使用$(())
或$[]
。
1 | [root@xuexi ~]# str=10 |
当然,在为变量赋算术值的时候也可以使用$(())
和$[]
。
1 | [root@xuexi ~]# str=10 |
其实,在算数计算过程中,等号右边的变量是可以带上$
符号的,但等号左边的变量不允许带上$
符号,因为它是要操作的变量,不是引用变量。例如:
1 | [root@xuexi ~]# let str=$str-1 # 等价于let str=str-1 |
还可以自增、自减运算。++
和--
表示变量自动加1和减1。但是位置不同,返回的结果是不同的。
1 | x++:先返回结果,再加1 |
假如x的初始值为10,则echo $[x++]
将显示10,但在显示完后(即返回结果之后),x的值已经变成了11,再执行echo $x
将返回11。
1 | [root@xuexi ~]# x=10;echo $((x++));echo $x |
如果此时再echo $[x++]
仍将返回11,但此时x已经是12了。
1 | [root@xuexi ~]# echo $((x++));echo $x |
再将x变量的初始值初始化为10,则echo $[++x]
将显示11,因为先加1后再赋值给x,echo再显示x的值。++x
完全等价于x=x+1
,它们都是先加1后赋值。
1 | [root@xuexi ~]# x=10;echo $((++x));echo $x |
同理自减也是一样的。
因此,在使用自增或自减进行变量赋值时,需要注意所赋的值是否加减立即生效的。例如:
1 | [root@xuexi ~]# x=10;y=$((x++));echo $y;echo $y |
因为y=$((x++))
赋给y的值是加1前的值,虽然赋值结束后,$((x++))
已经变成11,但这和y无关。
所以,对于自增自减类的变量赋值应该使用先计算再显示的”++x”或”–x”的方式。
1 | [root@xuexi ~]# x=10;y=$((++x));echo $y;echo $y |
总结下数值变量的赋值运算的方法:
1 | let i=i-1 |
除了变量可以数学运算,数组也一样支持数学运算,且和变量一样,都能支持自增和自减等操作。其实数组其实质就是变量,只不过变量在内存中是离散的空间,而数组在内存中是顺序的空间。
例如,数组arr_test[a]=10
,则:
1 | let arr_test[a]=${arr_test[0]} - 1 |
其它运算方法都类似,就不赘述了。其实和变量相比,只不过变量名改成arr_test[a]
,引用数组变量时改为${arr_test[a]}
。
bc命令高级算术运算
bc可用于浮点数的计算,是linux中的计算器。该命令功能丰富、强大的让人吐血,支持自定义变量、自定义函数表达式逻辑、支持科学计算等等。虽然功能丰富,但多数时候仅用它的基本计算功能。
以下是一个基本的功能示例:
1 | [root@node1 ~]# bc |
输入quit命令可以退出bc计算器。
还支持自增和自减的功能。
1 | [root@node1 ~]# bc -q |
bc运算器有一个内建的变量scale,用于表示计算的精度(其实是刻度),即小数位保留几位。默认刻度为0,所以除法运算的默认结果是整数。
1 | 13/(1+3) |
更人性化的功能是可以通过命令替换来实现批处理模式的计算。
它的一般格式参考如下:
1 | var=`echo "option1;option2;...;expression"|bc` |
其中options部分一般设置精度scale,和变量赋值,expression部分是计算表达式,最后将它们放在反引号中赋值给变量。如:
1 | [root@node1 ~]# area=`echo "scale=2;r=3;3.1415*r*r"|bc` |
由于是在命令行中指定,所以这样的使用方式限制较多。bc接受使用here string和here document的方式接收参数。最常做法是将它们放置于脚本中。
1 | #!/bin/bash |
当bc计算的结果小于1的时候,例如0.1+0.1=0.2
,它会显示.2
而不是显示”0.2”,要想显示出前面的0,bc自身似乎没有做出相关选项。不过可以通过外部程序,如printf将其显示出来。也可以结合echo命令显示。
1 | printf "%.2f\n" `echo "0.1 + 0.1" | bc` |
以下是计算1+2+...+10
的几种不同方式,要求输出在屏幕上的结果为1+2+3+4+5+6+7+8+9+10=计算结果
,这是非常不错的例子。
1 | [root@node1 tmp]# echo $(seq -s "+" 10)=`seq -s "+" 10|bc` |