shell 运算

Bash 数值运算以及支持的运算操作

本文内容来自 Shell:Shell 系列文章

Bash 数值运算

Bash 内置数值运算

使用 $(())$[] 或内置命令 letdeclare -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))

几个注意事项:

  1. 空变量或未定义变量或字符串变量参与数值运算时,都当作数值0
  2. 变量替换先于算术运算,所以既可以使用变量名var,也可使用变量引用$var,例如$[a+1]$[$a+1]在结果上是等价的
  3. 算术表达式可以进行嵌套,先计算最内层。如$(( (6+4)/$[2+3] ))
  4. 0开头的表示八进制,0x或0X开头的表示十六进制,可使用base#N的方式指定N是多少进制的数。例如echo $[ 010 + 10 ]得到18、echo $[ 0x10 + 10 ]得到26,echo $[ 2#100 + 10 ]得到14。参见下面一个实际案例
  5. 由上面的运算符可看出,$[]$(())以及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 ]
本博客已稳定运行 小时 分钟
共发表 31 篇文章 · 总计 82.93 k 字
本站总访问量
Built with Hugo
主题 StackJimmy 设计