本文内容来自 Shell:Shell 系列文章
Bash 数值运算
Bash 内置数值运算
使用 $(())
、$[]
或内置命令 let
或 declare -i
(以及等价的 typeset 命令) 可以进行数值运算,它们都只能进行整数运算。
- let 命令只能单独作为一个命令行运算
- declare -i 声明整数类型的变量,声明后就能直接参与数值运算
$(())
和 $[]
可以在命令内部进行运算,运算完成后会进行算术替换:即将运算结果替换到命令行中
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 使用let
n=1
let n=n+1
echo $n # 2
let n=$n+1
echo $n # 3
# 使用declare -i
declare -i a b c
a=10
b=100
c=a+b
echo $c # 110
# 使用$(())和$[]
x=10
y=20
echo $(( (x+y)*2 ))
echo $[ (x+y)*2 ]
|
小数运算
Bash 自身语法不支持小数运算。但如果真的需要进行精确到小数的运算,是可以借助其它命令工具,比如 bc、awk、perl 等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 使用awk
$ echo 1.2 2.3 | awk '{print $1+$2}'
3.5
$ awk 'BEGIN{print 1.2+2.3}'
3.5
# 使用bc
$ echo 1.2+2.3 | bc
3.5
# 使用perl
$ perl -E 'say 1.2+2.3'
3.5
$ echo 1.2 2.3 | perl -anE 'say $F[0]+$F[1]'
3.5
|
Bash 支持的运算操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
id++ id-- ++id --id
自增、自减
- +
一元运算符,即正负号
! ~
逻辑取反、位取反
**
幂运算
* / %
乘法、除法、取模
+ -
加法、减法
<< >>
位左移、位右移
&
按位与运算
^
按位异或运算
|
按位或运算
<= >= < >
大小比较
== !=
等值比较
&&
逻辑与
||
逻辑或
expr ? expr : expr
三目条件运算
= *= /= %= += -= <<= >>= &= ^= |=
各种赋值语句
expr1 , expr2
多个表达式,例如$((x+=1,y+=3,z+=4))
|
几个注意事项:
- 空变量或未定义变量或字符串变量参与数值运算时,都当作数值0
- 变量替换先于算术运算,所以既可以使用变量名
var
,也可使用变量引用$var
,例如$[a+1]
和$[$a+1]
在结果上是等价的
- 算术表达式可以进行嵌套,先计算最内层。如
$(( (6+4)/$[2+3] ))
- 0开头的表示八进制,0x或0X开头的表示十六进制,可使用base#N的方式指定N是多少进制的数。例如
echo $[ 010 + 10 ]
得到18、echo $[ 0x10 + 10 ]
得到26,echo $[ 2#100 + 10 ]
得到14。参见下面一个实际案例
- 由上面的运算符可看出,
$[]
、$(())
以及let命令,既支持算术运算,还支持赋值、大小比较、等值比较。如a=3;echo $[a==3]
有时候从字符串中截取得到的数值是以0开头的,如果要让它参与运算,需要指定为十进制,否则会当作八进制。例如:
1
2
3
4
5
6
7
|
datetime1=`date +"%s.%N"`
nano_seconds1=${datetime1#*.}
sleep 1
datetime2=`date +"%s.%N"`
nano_seconds2=${datetime2#*.}
echo $[ 10#$nano_seconds2 - 10#$nano_seconds1 ]
|