Shell中的数学计算

Shell数学计算(算术运算,加减乘除运算)

如果要执行算术运算(数学计算),就离不开各种运算符号,和其他编程语言类似,Shell 也有很多算术运算符,下面就给大家介绍一下常见的 Shell 算术运算符,如下表所示。

Shell 算术运算符一览表 算术运算符      说明/含义

+、-      加法(或正号)、减法(或负号)

*、/、% 乘法、除法、取余(取模)

**    幂运算

++、-- 自增和自减,可以放在变量的前面也可以放在变量的后面

!、&&、||      逻辑非(取反)、逻辑与(and)、逻辑或(or)

<、<=、>、>=   比较符号(小于、小于等于、大于、大于等于)

==、!=、=   比较符号(相等、不相等;对于字符串,= 也可以表示相当于)

<<、>>        向左移位、向右移位

~、|、 &、^       按位取反、按位或、按位与、按位异或

=、+=、-=、*=、/=、%= 赋值运算符,例如 a+=1 相当于 a=a+1,a-=1 相当于 a=a-1

 

# 但是,Shell 和其它编程语言不同,Shell 不能直接进行算数运算,必须使用数学计算命令,这让初学者感觉很困惑,也让有经验的程序员感觉很奇葩

下面我们先来看一个反面的例子:

[root@server1 mnt]# echo 2+8

2+8

[root@server1 mnt]# a=23

[root@server1 mnt]#  b=$a+55

[root@server1 mnt]# echo $b

23+55

[root@server1 mnt]#  b=90

[root@server1 mnt]#  c=$a+$b

[root@server1 mnt]# echo $c

23+90

# 从上面的运算结果可以看出,默认情况下,Shell 不会直接进行算术运算,而是把+两边的数据(数值或者变量)当做字符串,把+当做字符串连接符,最终的结果是把两个字符串拼接在一起形成一个新的字符串

# 这是因为,在 Bash Shell 中,如果不特别指明,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储 换句话说,Bash shell 在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同

数学计算命令

要想让数学计算发挥作用,必须使用数学计算命令,Shell 中常用的数学计算命令如下表所示

Shell 中常用的数学计算方式 运算操作符/运算命令     说明

(( )) 用于整数运算,效率很高,推荐使用。

let   用于整数运算,和 (()) 类似。

$[] 用于整数运算,不如 (()) 灵活。

expr       可用于整数运算,也可以处理字符串。比较麻烦,需要注意各种细节,不推荐使用。

bc   Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。

如果大家时间有限,只学习 (()) 和 bc 即可,不用学习其它的了:(()) 可以用于整数计算,bc 可以小数计算

Shell (( )) 的用法

双小括号 (( )) 的语法格式为:

((表达式))

通俗地讲,就是将数学运算表达式放在((和))之间

表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( )) 命令的执行结果

可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的

# 这种写法可以在计算完成后给变量赋值。以 ((b=a-15)) 为例,即将 a-15 的运算结果赋值给变量 c 注意,使用变量时不用加$前缀,(( )) 会自动解析变量名

[root@server1 mnt]# ((a=10+66))

[root@server1 mnt]# ((b=a-15))

[root@server1 mnt]# ((c=a+b))

[root@server1 mnt]# echo $c

137

[root@server1 mnt]# a=10+66

[root@server1 mnt]# echo $a

10+66

 

可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c

注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果

[root@server1 mnt]# a=$((10+66))

[root@server1 mnt]# b=$((a-15))

[root@server1 mnt]# c=$((a+b))

[root@server1 mnt]# echo $c

137

实例演示:

【实例1】利用 (( )) 进行简单的数值计算

[root@server1 mnt]# echo $((1+1))

2

[root@server1 mnt]# echo $((6-3))

3

[root@server1 mnt]# i=5

[root@server1 mnt]# ((i=i*2)) #可以简写为 ((i*=2))

[root@server1 mnt]#  echo $i  #使用 echo 输出变量结果时要加 $

10

 

【实例2】用 (( )) 进行稍微复杂一些的综合算术运算

[root@server1 mnt]#  ((a=1+2**3-4%3))

[root@server1 mnt]# echo $a

8

[root@server1 mnt]# b=$((1+2**3-4%3))  #运算后将结果赋值给变量,变量放在了括号的外面

[root@server1 mnt]# echo $b

8

[root@server1 mnt]# echo $((1+2**3-4%3)) #也可以直接将表达式的结果输出,注意不要丢掉 $ 符号

8

[root@server1 mnt]#  a=$((100*(100+1)/2)) #利用公式计算1+2+3+...+100的和

[root@server1 mnt]# echo $a

5050

[root@server1 mnt]# echo $((100*(100+1)/2)) #也可以直接输出表达式的结果

5050

【实例3】利用 (( )) 进行逻辑运算

[root@server1 mnt]#  echo $((3<8))

1

[root@server1 mnt]#  echo $((8<3))

0

[root@server1 mnt]# echo $((8==8))

1

【实例4】利用 (( )) 进行自增(++)和自减(--)运算

[root@server1 mnt]# a=10

[root@server1 mnt]#  echo $((a++))  #如果++在a的后面,那么在输出整个表达式时,会输出a的值,因为a为10,所以表达式的值为10

10

[root@server1 mnt]# echo $a #执行上面的表达式后,因为有a++,因此a会自增1,因此输出a的值为11

11

[root@server1 mnt]# echo $((a--))  #如果--在a的后面,那么在输出整个表达式时,会输出a的值,因为a为11,所以表达式的值的为11

11

[root@server1 mnt]#  echo $a #执行上面的表达式后,因为有a--,因此a会自动减1,因此a为10

10

[root@server1 mnt]# a=10

[root@server1 mnt]# echo $((--a))  #如果--在a的前面,那么在输出整个表达式时,先进行自增或自减计算,因为a为10,且要自减,所以表达式的值为9

9

[root@server1 mnt]#  echo $a  #执行上面的表达式后,a自减1,因此a为9

9

[root@server1 mnt]#  echo $((++a))   #如果++在a的前面,输出整个表达式时,先进行自增或自减计算,因为a为9,且要自增1,所以输出10

10

[root@server1 mnt]# echo $a  #执行上面的表达式后,a自增1,因此a为10

10

 

 执行 echo $((a++)) 和 echo $((a--)) 命令输出整个表达式时,输出的值即为 a 的值,表达式执行完毕后,会再对 a 进行 ++、-- 的运算;

而执行 echo $((++a)) 和 echo $((--a)) 命令输出整个表达式时,会先对 a 进行 ++、-- 的运算,然后再输出表达式的值,即为 a 运算后的值

 

实例5】利用 (( )) 同时对多个表达式进行计算

[root@server1 mnt]# ((a=3+5, b=a+10)) #先计算第一个表达式,再计算第二个表达式

[root@server1 mnt]# echo $a $b

8 18

[root@server1 mnt]#  c=$((4+8, a+b)) #以最后一个表达式的结果作为整个(())命令的执行结果

[root@server1 mnt]#  echo $c

26

Shell let命令:对整数进行数学运算

let 命令和双小括号 (( )) 的用法是类似的,它们都是用来对整数进行运算

# 注意:和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算

Shell let 命令的语法格式为:

let 表达式

或者

let "表达式"

或者

let '表达式'

它们都等价于((表达式))

和 (( )) 类似,let 命令也支持一次性计算多个表达式,并且以最后一个表达式的值作为整个 let 命令的执行结果。但是,对于多个表达式之间的分隔符,let 和 (( )) 是有区别的:

    let 命令以空格来分隔多个表达式;

    (( )) 以逗号,来分隔多个表达式

 

另外还要注意,对于类似let x+y这样的写法,Shell 虽然计算了 x+y 的值,但却将结果丢弃;若不想这样,可以使用let sum=x+y将 x+y 的结果保存在变量 sum 中

 

这种情况下 (( )) 显然更加灵活,可以使用$((x+y))来获取 x+y 的结果

[root@server1 mnt]#  a=10 b=20

[root@server1 mnt]# echo $((a+b))

30

[root@server1 mnt]#  echo let a+b

let a+b

[root@server1 mnt]#  echo let c=a+b

let c=a+b

[root@server1 mnt]# a=10 b=20

[root@server1 mnt]# let c=a+b

[root@server1 mnt]# echo $c

30

 

 

【实例1】给变量 i 加 8

Shell let 命令实例演示

[root@server1 mnt]# i=2

[root@server1 mnt]#  let i+=8

[root@server1 mnt]#  echo $i

10

 

let i+=8 等同于 ((i+=8)),但后者效率更高

 

【实例2】let 后面可以跟多个表达式

[root@server1 mnt]# a=10 b=35

[root@server1 mnt]# let a+=6 c=a+b

[root@server1 mnt]# echo $a $c

16 51

 

expr用于计算

[root@server1 mnt]# expr 2+2

2+2

[root@server1 mnt]# expr 2-2

2-2

[root@server1 mnt]# expr 2*2

2*2

[root@server1 mnt]# expr 2、*2

2、*2

[root@server1 mnt]# expr 2\*2

2*2

[root@server1 mnt]# expr 2/2

2/2

[root@foundation0 day01]# expr 2 + 2

4

[root@foundation0 day01]# expr 2 - 2

0

[root@foundation0 day01]# expr 2 * 2

expr: syntax error

[root@foundation0 day01]# expr 2 、* 2

expr: syntax error

[root@foundation0 day01]# expr 2 \* 2

4

[root@foundation0 day01]# expr 2 / 2

1

 

 

 

注意:在使用expr时

1.运算符及用于计算的数字左右都至少有一个空格,都则会报错

2.使用乘号时,必须用\屏蔽其特定的含义 因为shell可能会误解*的含义

 

expr配合变量计算

expr在shell中可配合变量进行计算 但需要用反引号将计算表达式括起来

[root@server1 mnt]# i = 5

-bash: i: command not found

[root@server1 mnt]# i = `expr $i + 6`

-bash: i: command not found

[root@server1 mnt]# i=`expr $i + 6`

[root@server1 mnt]# echo $i

16

[root@server1 mnt]# i=5

[root@server1 mnt]# i=`expr $i + 6`

[root@server1 mnt]# echo $i

11

 

 

bc命令

bc是unix/linux下的计算器,因此 除了可以作为计算器来使用 还可以作为命令行计算工具使用

[root@server1 mnt]# yum whatprovides */bc

Loaded plugins: product-id, search-disabled-repos, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

rhel7.5                                                  | 4.3 kB     00:00    

bc-1.06.95-13.el7.x86_64 : GNU's bc (a numeric processing language) and dc (a

                         : calculator)

Repo        : rhel7.5

Matched from:

Filename    : /usr/bin/bc

 

[root@server1 mnt]# yum install bc-1.06.95-13.el7.x86_64 -y

 

[root@server1 mnt]# 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.2

2.3

 

 

[root@server1 mnt]# echo 3+5|bc

8

[root@server1 mnt]# echo 3.3+5.3|bc

8.6

[root@server1 mnt]# echo 9.9-5.3|bc

4.6

[root@server1 mnt]# echo 9-50|bc

-41

[root@server1 mnt]# echo "scale=2;355/113"|bc #保留两位小数

3.14

[root@server1 mnt]# echo "scale=6;355/113"|bc

3.141592

 

配合变量使用

[root@server1 mnt]# i=5

[root@server1 mnt]# i=`echo $i+6|bc`

[root@server1 mnt]# echo $i

11

 

 

$[]符号的运算式例子

[root@server1 mnt]# i=5

[root@server1 mnt]# i=$[i+6]

[root@server1 mnt]# echo $i

11

[root@server1 mnt]# echo $[2*3]

6

[root@server1 mnt]# echo $[2**3]

8

[root@server1 mnt]# echo $[3/5]

0

[root@server1 mnt]# echo $[3/2]

1

[root@server1 mnt]# echo $[3%2]

1

[root@server1 mnt]# echo $[3%5]

3

[root@server1 mnt]# echo $[ 3 % 5 ]

3

[root@server1 mnt]# echo $[ 3 / 5 ]

0

 

 

 

 

 

 

 

 

 

 

 

发布了68 篇原创文章 · 获赞 14 · 访问量 1469

猜你喜欢

转载自blog.csdn.net/qq_41871875/article/details/104282838