五、Shell的变量之五变量的算数运算

一、算数运算符

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

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

**
幂运算

++、——
增加及减少,可前置也可放在变量结尾

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

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

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

<<、>>
向左移位、向有移位

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

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

二、运算操作符与运算命令

(())
用于整数运算的常用运算符,效率很高

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

expr
可用于整数运算,但也有很多其他的额外功能

bc
Linux下的一个计算器程序(适合整数和小数运算)

$[]
用于整数运算

awk
即可以用于整数计算,也可以用于小数计算

declare
定义变量值和属性,-i参数可以用于定义整形变量,做运算

三、实验案例

1、双小括号"(())"

"(())"的运算

((i=i+1))
运算后赋值法,即将i+1的值赋值给i,不能用"echo ((i=i+1))"的形式输出表达式的值,但可以用"echo $((i=i+1))"输出其值。

[root@node1 ~]# echo ((i=7+6))
-bash: syntax error near unexpected token `('
#上面为错误的输出
[root@node1 ~]# echo $((i=7+6))
13

[root@node1 ~]# ((a=1+2**3-4%3))
[root@node1 ~]# echo $a
8
等价于
[root@node1 ~]# echo $((1+2**3-4%3))
8

[root@node1 ~]# a=10
[root@node1 ~]# echo $((a**2))
100

特殊运算符号

[root@node1 ~]# echo $a
8
[root@node1 ~]# echo $((1+2**3-4%3))
8
[root@node1 ~]# a=8
[root@node1 ~]# echo $((a=a+1))
9
[root@node1 ~]# echo $((a+=1)) #====echo $((a=a+1))
10

"(())"的比较及判断

"(())"的比较,真值为1,假值为0
[root@node1 ~]# echo $((3<8))
1
[root@node1 ~]# echo $((3>8))
0
[root@node1 ~]# echo $((3==3))
1

判断
[root@node1 ~]# if((8>7&&5==5))
> then
> echo yes
> fi
yes
#如果8>7且5==5,则打印yes

++的特殊运算表达式

[root@node1 ~]# a=10
[root@node1 ~]# echo $((a++))
10
[root@node1 ~]# echo $a
11
#执行完表达式后,a会自增1,再把值赋值给a
[root@node1 ~]# a=10
[root@node1 ~]# echo $((a--))
10
[root@node1 ~]# echo $a
9
#执行完表达式后,a会自减1,再把值赋值给a

[root@node1 ~]# a=10
[root@node1 ~]# echo $((++a))
11
[root@node1 ~]# echo $a
11
#先给a增加1,再执行表达式
[root@node1 ~]# a=10
[root@node1 ~]# echo $((--a))
9
[root@node1 ~]# echo $a
9
#先给a减少1,再执行表达式
++、——运算的记忆方法:
变量a在运算符之前,输出表达式的值为a,然后a自增或自减;变量a在运算符之后,输出表达式会先自增或自减,表达式的值就是自增或自减后a的值。

运算后赋值给变量

[root@node1 ~]# a=10
[root@node1 ~]# a=$((a+1))
[root@node1 ~]# echo $a
11
1) "(())"表达式在命令行执行时不需要加$符号,直接使用((6%2))形式即可,但是如果需要输出,就要加$符,例如:echo $((6%2))。
2) "(())"里的所有字符之间没有空格、有一个或多个空格都不会影响结果。

各种"(())"运算的shell脚本案例

#!/bin/bash
a=6                    #<==在脚本中定义a和b两个变量并分别赋值。
b=2
echo "a-b=$(($a-$b))"  #<==对定义的变量值进行各种符号运算,并通过表达式的形式输出,下同。
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))"

结果
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0

2、let运算命令的用法

let运算命令的语法格式为:let赋值表达式

let赋值表达式的功能等同于“((赋值表达式))”

[root@node1 ~]# a=10
[root@node1 ~]# let a=a+2
[root@node1 ~]# echo $a
12
相当于
[root@node1 ~]# a=10
[root@node1 ~]# a=$((a+2))
[root@node1 ~]# echo $a
12

3、expr命令的用法

expr用于计算

[root@node1 ~]# expr 2 + 2
4
[root@node1 ~]# expr 2 * 2
expr: syntax error
[root@node1 ~]# expr 2 \* 2
4
[root@node1 ~]# expr 2 / 2
1
[root@node1 ~]# expr 2 % 2
0

要注意,在使用expr时:
·运算符及用于计算的数字左右都至少有一个空格,否则会报错。
·使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。

expr配合变量计算

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

[root@node1 ~]# a=10
[root@node1 ~]# b=`expr $a + 6`
[root@node1 ~]# echo $b
16

判断一个变量值或字符串是否为整数

实现原理是,利用以expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回的值是否为0。如果为0,就认为做加法的变量或字符串为整数,否则就不是整数。

[root@node1 ~]# i=5
[root@node1 ~]# expr $i + 6 &>/dev/null
[root@node1 ~]# echo $?
0

[root@node1 ~]# i=kaka
[root@node1 ~]# expr $i + 6 &>/dev/null
[root@node1 ~]# echo $?
2
#利用expr做计算,将一个未知的变量和一个已知的整数相加,看返回值是否为0,如果为0就认为做加法的变量为整数,否则就不是整数。

通过传参判断输出内容是否为整数

[root@node1 tmp]# cat expr.sh
#!/bin/sh
expr $1 + 1 >/dev/null 2>&1
[ $? -eq 0 ] &&echo int||echo chars  #<==这是一个条件表达式语法,返回值为0,则输出int,否则输出chars。
[root@node1 tmp]# sh /tmp/expr.sh 5
int
[root@node1 tmp]# sh /tmp/expr.sh kaka
chars

expr的特殊用法:判断文件扩展命名是否符合要求

[root@node1 tmp]# cat expr1.sh
#!/bin/sh
if expr "$1" : ".*\.pub" &>/dev/null
  then
    echo "you are using $1"
else
    echo "pls use *.pub file"
fi
[root@node1 tmp]# sh expr1.sh kaka
pls use *.pub file
[root@node1 tmp]# sh expr1.sh king.pub
you are using king.pub

通过expr计算字符串的长度

[root@node1 tmp]# a="ni hao da hai"
[root@node1 tmp]# expr length "$a"
13
#包含空格

4、bc命令的用法

将bc作为计算器来应用

[root@node1 tmp]# 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
2
[root@node1 tmp]# echo 3+4|bc
7
[root@node1 tmp]# echo 3.3+4|bc
7.3
[root@node1 tmp]# echo 8.3+4.7|bc
13.0
[root@node1 tmp]# echo 8.3-4.7|bc
3.6
[root@node1 tmp]# echo "scale=2;8.3-4.7"|bc
3.6
[root@node1 tmp]# echo "scale=2;8.3/4.7"|bc
1.76
[root@node1 tmp]# echo "scale=6;355/113"|bc   #scale保留小数点后几位
3.141592

利用bc配合变量运算

[root@node1 tmp]# i=5
[root@node1 tmp]# i=`echo $i+6|bc`
[root@node1 tmp]# echo $i
11

5、awk实现计算

利用awk进行运算的效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确
[root@node1 tmp]# echo "7.8 4.5"|awk '{print ($1-$2)}'
3.3
[root@node1 tmp]# echo "358 113" |awk '{print ($1-3)/$2}'
3.14159
[root@node1 tmp]# echo "3 9" |awk '{print ($1+3)*$2}'
54

6、declare(同typeset)命令的用法

[root@node1 tmp]# declare -i A=30 B=7 #<==declare -i参数可以将变量定义为整形。
[root@node1 tmp]# A=A+B  #<==因为已声明是整型,因此可以直接进行运算了。
[root@node1 tmp]# echo $A
37  #<==结果为37

7、$[]符号的运算示例

[root@node1 tmp]# i=5
[root@node1 tmp]# i=$[i+6]
[root@node1 tmp]# echo $i
11
[root@node1 tmp]# echo $[2*3]
6
[root@node1 tmp]# echo $[2**3]
8
[root@node1 tmp]# echo $[3/5]
0
[root@node1 tmp]# echo $[3/2]
1
[root@node1 tmp]# echo $[3%5]
3
[root@node1 tmp]# echo $[ 3 % 5 ]
3

四、基于Shell变量输入read命令的运算实践

Shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入中获得,read为bash内置命令,可通过help read查看帮助。
语法格式:read[参数][变量名]

常用参数如下。
·-p prompt:设置提示信息。
·-t timeout:设置输入等待的时间,单位默认为秒。

实现read的基本读入功能。

[root@node1 tmp]# read -t 10 -p "Pls input one num:" num
#<==读入一个输入,赋值给num变量,注意,num变量前需要有空格。
Pls input one num:18             #<==输出数字18,相当于把18赋值给num变量。
[root@node1 tmp]# echo $num #<==输出变量值。
[root@node1 tmp]# read -p "please input two number:" a1 a2
#<==读入两个输入,注意要以空格隔开,分别赋值给a1和a2变量,a1变量前后都需要有空格。
please input two number:1 2
[root@node1 tmp]# echo $a1
1
[root@node1 tmp]# echo $a2
2

把前面加减乘除计算传参的脚本改成通过read方式读入整数变量

#!/bin/bash
read -t 15 -p "please input two number:" a b  #<==去掉原脚本中a和b的定义,通
                                                 过read读入即可。
echo "a-b=$(($a-$b))"
echo "a+b=$(($a+$b))"
echo "a*b=$(($a*$b))"
echo "a/b=$(($a/$b))"
echo "a**b=$(($a**$b))"
echo "a%b=$(($a%$b))"

 

上一篇:9.12 模拟赛简要回顾


下一篇:shell编程--2