Shell中的算术运算

933 阅读4分钟

Shell允许在某些情况下对算术表达式进行求值,比如:let和declare 内置命令,(( ))复合命令和算术扩展。求值以固定宽度的整数进行,不检查溢出。

注意:默认情况下bash只支持整数运算,不支持小数运算。

1 运算表达式

运算表达式:

 (1) expr 变量1 运算符 变量2  [运算符 变量3]...
 (2) let var=算术表达式
 (3) ((var=算术表达式)),和上一个等价
 (4) var=$[算术表达式]
 (5) var=$((算术表达式))
 (6) var=$(expr arg1 arg2 arg3 ...)
 (7) var= `expr arg1 arg2 arg3 ...`
 (8) echo '算术表达式' | bc

运算符:

  • 加法 +
  • 减法 -
  • 乘法 \ *
  • 除法 /
  • 取余 (取模)%

运算法则:

  • 加法: num1 + num2
  • 减法:num1 - num2
  • 乘法:num1 \ * num2
  • 整除:num1 / num2
  • 取余(求模):num1 % num2 (求 num1 除以 num2 的余数)

2 运算演示

2.1 expr

expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串。

  • 变量和运算符之间,要用空格隔开。
  • 用反斜杠 \ 放在 shell 特定的字符前面;
  • 对包含空格和其他特殊字符的字符串要用引号括起来

示例1:

 [root@localhost ~]# expr 4 + 3
 7
 [root@localhost ~]# expr 4 - 3
 1
 [root@localhost ~]# expr 4 * 3     //乘号前要加反斜杠
 12
 [root@localhost ~]# expr 10 / 2
 5
 [root@localhost ~]# expr 10 % 3     //10除以3取余数
 1
 [root@localhost ~]# expr 1 + 2 \* 3    //先乘除,再加减
 7

expr1.png

示例2:

 [root@localhost ~]# a=1
 [root@localhost ~]# b=2
 [root@localhost ~]# expr $a + $b
 3
 [root@localhost ~]# expr $a - $b
 -1
 [root@localhost ~]# expr $a * $b
 2

expr2.png

示例3:

$( )和反撇号,可以调用命令的执行结果。

 [root@localhost ~]# echo $(expr 3 + 4 - 1)
 6
 [root@localhost ~]# i=$(expr 2 + 5 * 3)
 [root@localhost ~]# echo $i
 17
 [root@localhost ~]# m=`expr 1 + 2`
 [root@localhost ~]# echo $m
 3

expr3.png

2.2 let 和 (( ))

let var=算术表达式((var=算术表达式)) 效果等同。

两者都不返回结果,需要借助echo命令。

示例1:

 [root@localhost ~]# let y=1+2
 [root@localhost ~]# echo $y
 3
 [root@localhost ~]# ((z=1+2))
 [root@localhost ~]# echo $z
 3

let.png 示例2:

 [root@localhost ~]# a=30
 [root@localhost ~]# b=20
 [root@localhost ~]# let cc=$a+$b      //加法
 [root@localhost ~]# echo $cc
 50
 [root@localhost ~]# let dd=$a-$b      //减法
 [root@localhost ~]# echo $dd
 10
 [root@localhost ~]# let ee=$a*$b      //乘法
 [root@localhost ~]# echo $ee
 600
 [root@localhost ~]# let ff=$a%$b     //取余数
 [root@localhost ~]# echo $ff
 10
 [root@localhost ~]# let gg=$a/$b     //整除的商
 [root@localhost ~]# echo $gg
 1

let2.png

2.3$[ ] $(( ))

$[ ]$(( ))效果相同,且都支持对变量进行运算。

 [root@localhost ~]# echo $[10+3]
 13
 [root@localhost ~]# echo $[10-3]
 7
 [root@localhost ~]# echo $[10*3]
 30
 [root@localhost ~]# echo $[10/3]
 3
 [root@localhost ~]# echo $[10%3]
 1
 [root@localhost ~]# a=2
 [root@localhost ~]# b=5
 [root@localhost ~]# echo $[a+b]
 7
 [root@localhost ~]# echo $[a*b]
 10
 [root@localhost ~]# echo $((a+b))
 7
 [root@localhost ~]# echo $((a*b))
 10

美元1.png

美元2.png

3 小数运算(浮点数运算)

3.1 使用bc计算器

Bash内置了对整数运算的支持,但是并不支持浮点运算,而 bc 计算器可以很方便的进行浮点运算。

  • 支持交互式和非交互式两种方式。
  • 使用scale=n可以指定精度,即小数点后的位数。要写在算术表达式之前。
  • 非交互式运算,使用 echo "算术表达式" | bc。 多个算术表达式之间用分号隔开,例如:echo '1+1;2+2" | bc。

示例1:

交互式运算

 [root@localhost ~]# bc
 bc 1.06.95
 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, 
 Inc.
 This is free software with ABSOLUTELY NO WARRANTY.
 For details type `warranty'.
 1.1*1.1            //输入1.1*1.1,敲回车
 1.2                //返回结果
 3.3+3.3            
 6.6
 scale=2           //指定精度,小数点后显示2位
 1.1*1.1           //输入1.1*1.1,敲回车
 1.21              //显示2位小数
 quit              //退出计算器
 [root@localhost ~]#

bc1.png

示例2:

非交互式运算,使用:echo "算术表达式" | bc。

使用scale指定精度时,要写在算术表达式之前。

 [root@localhost ~]# echo "1.1+1.1" |bc
 2.2
 [root@localhost ~]# echo "2+2.2;3.3+3.3" |bc    //多个算术表达式之间用分号隔开
 4.2
 6.6
 [root@localhost ~]# echo "scale=2;1.5*1.5;3.6*3.6" |bc   //scale=2指定小数点后显示2位
 2.25
 12.96
 [root@localhost ~]# echo "scale=3;10/2" |bc    //scale=3指定小数点后显示3位
 5.000

bc2.png

3.2 使用awk命令

使用awk进行浮点数的运算,运算结果最多显示6个有效数字。

格式:awk "BEGIN{print 算术表达式}"

示例:

 [root@localhost ~]# awk "BEGIN{print 6.5+3.4}"
 9.9
 [root@localhost ~]# awk "BEGIN{print 6.5-3.4}"
 3.1
 [root@localhost ~]# awk "BEGIN{print 6.5*3.4}"
 22.1
 [root@localhost ~]# awk "BEGIN{print 6.5/3.4}"
 1.91176
 [root@localhost ~]# awk "BEGIN{print (6.5-3.4)*7}"     //混合运算
 21.7

awk.png

4 变量的自增和自减

简写表达式等同于
let i++i=$[$i+1]
let i--i=$[$i-1]
let i+=2i=$[$i+2]
let i-=2i=$[$i-2]
let i*=2i=$[$i*2]
let i/=2i=$[$i/2]
let i%=2i=$[$i%2]

示例1:

使用分号,可以在一行执行多个命令。

 [root@localhost ~]# i=1
 [root@localhost ~]# let i++        //i1
 [root@localhost ~]# echo $i
 2
 [root@localhost ~]# let i--       //i1
 [root@localhost ~]# echo $i
 1
 [root@localhost ~]# let i+=2      //i2
 [root@localhost ~]# echo $i
 3
 [root@localhost ~]# let i*=3;echo $i       //i3
 9
 [root@localhost ~]# let i/=3;echo $i       //i除以3 
 3
 [root@localhost ~]# let i%=2;echo $i       //i除以2后取余数
 1

自增.png

示例2:

比较 i++ 和 ++i:

i++ 是先赋值再自增; ++i 是自增后再赋值。

 [root@localhost ~]# i=1;let i++; echo $i
 2
 [root@localhost ~]# i=1;let ++i; echo $i
 2
 [root@localhost ~]# i=100;let z=i++; echo $i $z   //i++是先赋值给z后再自增
 101 100
 [root@localhost ~]# i=100;let z=++i; echo $i $z   //++i是先自增后再赋值给z
 101 101

自增2.png

5 生成随机数

使用 echo $[RANDOM%n] 可以生成随机数,n为正整数。

对 n 取余数的范围是 [0,n-1]。

  • echo $[RANDOM%10]生成的随机数范围为 [0,9]
  • 如果希望包含10的话,可以echo $[RANDOM%11],则随机数范围为 [0,10]。
  • 如果希望随机数范围都为正整数,即不包含0的话,可以echo $[RANDOM%10+1],此时随机数范围为[1,10]。
 # 要求生成20以内的随机数,不包括20
 [root@localhost ~]# echo $[RANDOM % 20]
 12
 [root@localhost ~]# echo $[RANDOM % 20]
 0
 [root@localhost ~]# echo $[RANDOM % 20]
 7
 ​
 # 要求生成15以内的正整数,包括15
 [root@localhost ~]# echo $[RANDOM%15+1]
 9
 [root@localhost ~]# echo $[RANDOM%15+1]
 14
 [root@localhost ~]# echo $[RANDOM%15+1]
 8

随机数1.png

随机数2.png

6 总结

常用的运算表达式:

 # 常用的四个运算表达式:
 i=$(expr 12 * 5 )
 i=$((12*5))
 i=$[12*5]
 let i=12*5
 ​
 # 变量的自增和自减等
 let i++    等同于 i=$[$i+1]
 let i--    等同于 i=$[$i-1]
 let i+=2   等同于 i=$[$i+2]
 let i-=2   等同于 i=$[$i-2]
 let i/=2   等同于 i=$[$i/2]
 ​
 # 生成随机数
 echo $[RANDOM%n]    //生成n以内的随机数,不包括n