【网络运维】Shell:变量数值计算
Shell 变量数值计算
算术运算符概览
在 Shell 编程中,进行数值运算离不开各种运算符。与其他编程语言类似,Shell 也提供了丰富的算术运算符来满足不同的计算需求。
常用算术运算符
- 基本运算:
+
(加法)、-
(减法)、*
(乘法)、/
(除法)、%
(取模) - 幂运算:
**
(指数运算) - 自增自减:
++
、--
(可前置或后置) - 比较运算:
<
、<=
、>
、>=
、==
、!=
- 逻辑运算:
!
(非)、&&
(与)、||
(或) - 位运算:
~
(取反)、&
(与)、|
(或)、^
(异或)、<<
(左移)、>>
(右移) - 赋值运算:
=
、+=
、-=
、*=
、/=
、%=
Shell 中的算术运算命令
(())
:高效整数运算let
:整数运算,功能类似(())
expr
:多功能表达式求值工具bc
:支持整数和小数运算的计算器$[]
:整数运算(已逐渐被$(())
取代)awk
:强大的文本处理与数值计算工具declare
:通过-i
参数定义整型变量
(()) 双小括号数值运算
双小括号(())
是 Shell 中进行数值运算和比较的高效方式,被广泛用于企业级脚本开发。
基础语法
# 运算后赋值
((i = i + 1))# 带$符号的表达式求值
i=$((i + 1))# 比较操作
((8 > 7 && 5 == 5))# 直接输出结果
echo $((2 + 1))
实战示例
例1: 简单数值计算
$ echo $((1 + 1))
2
$ echo $((6 * 3))
18
$ ((i = 5))
$ ((i = i * 2))
$ echo $i
10
例2: 复杂表达式计算
$ ((a = 1 + 2**3 - 4%3))
$ echo $a
8$ a=$((100 * (100 + 1) / 2))
$ echo $a
5050
例3: 特殊运算符使用
$ a=8; echo $((a += 1))
9
$ echo $((a**2))
81
例4: 比较与判断
$ ((3 < 8)); echo $?
0
$ echo $((3 < 8))
1$ if ((8 > 7 && 5 == 5)); then echo "yes"; fi
yes
例5: 自增自减操作
$ a=10
$ echo $((a++)) # 输出10,然后a变为11
10
$ echo $a
11$ echo $((--a)) # 先减1再输出,输出10
10
注意:后置
a++
先返回值再运算,前置++a
先运算再返回值。
let 命令
let
命令用于整数运算,功能等同于(())
,但语法略有不同。
$ i=2
$ i=i+8 # 错误方式
$ echo $i
i+8$ i=2
$ let i=i+8 # 正确方式
$ echo $i
10# 等效的(())写法
$ i=2
$ ((i = i + 8))
$ echo $i
10
expr 命令
expr
是一个功能强大的表达式求值工具,既可进行整数运算,也可处理字符串操作。
基本用法
$ expr 2 + 2 # 正确:运算符两边有空格
4$ expr 2+2 # 错误:缺少空格
2+2$ expr 2 * 2 # 错误:*需要转义
expr: syntax error$ expr 2 \* 2 # 正确:使用转义
4
实战案例
例1: 判断变量是否为整数
$ i=5
$ expr $i + 5 > /dev/null 2>&1
$ echo $?
0 # 返回0表示是整数$ i="abc"
$ expr $i + 5 > /dev/null 2>&1
$ echo $?
2 # 返回非0表示不是整数
例2: 使用正则匹配判断整数
$ i="abc"
$ expr match "$i" "^[0-9]\+$" > /dev/null
$ echo $?
1 # 非整数$ i=123
$ expr match "$i" "^[0-9]\+$" > /dev/null
$ echo $?
0 # 整数
例3: 文件扩展名验证
$ file="stu-202212.jpg"
$ expr "$file" : ".*\.jpg$" > /dev/null
$ echo $?
0 # jpg扩展名$ expr "$file" : ".*\.pub$" > /dev/null
$ echo $?
1 # 非pub扩展名
例4: 字符串长度计算
$ str="abc123abc123"
$ expr length "$str"
12
例5: 筛选短单词
#!/bin/bash
strings="This is Linux World Welcome to our classroom"
for word in $strings
doif [ $(expr length "$word") -le 6 ]; thenecho $wordfi
done
输出结果:
This
is
Linux
World
to
our
bc 命令:精度计算利器
bc
是 Linux 下的计算器程序,支持高精度数学运算。
交互式使用
$ 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+3*4-6/3^3%4
13
scale=4 # 设置小数位数为4
1/3
.3333
quit
管道方式使用
$ echo '1+3*4-6/3^3%4' | bc
13$ echo 'scale=4;1/3' | bc
.3333# 计算1到10的和
$ echo $(seq -s + 10) | bc
55
awk:文本与数值处理专家
awk
不仅擅长文本处理,还能进行精确的数值计算,特别适合小数运算。
$ echo "7.7 3.8" | awk '{print $1 - $2}'
3.9$ echo "358 113" | awk '{print ($1-3)/$2}'
3.14159# 计算平均值
$ echo "10 20 30" | awk '{sum=0; for(i=1;i<=NF;i++)sum+=$i; print sum/NF}'
20
$[ ] 符号运算
$[]
是另一种整数运算方式,但逐渐被$(())
取代。
$ echo $[1 + 1]
2
$ echo $[4 / 2]
2
$ echo $[5 / 2] # 整数除法
2# 复杂表达式
$ count=3
$ echo $[(count + 1) * 3]
12# 自增操作
$ count=3
$ echo $[++count + 3] # 先增后计算:4+3=7
7
$ echo $[count++ + 3] # 先计算后增:3+3=6
6
综合实战:计算1到10的和
多种方式实现1到10的累加:
# 使用seq和bc
$ echo $(seq -s + 10) | bc
55# 使用大括号展开和tr
$ echo $(( $(echo {1..10} | tr ' ' '+') ))
55# 使用awk
$ echo "" | awk '{for(i=1;i<=10;i++)sum+=i; print sum}'
55# 使用(())
$ echo $(( (10*(10+1))/2 ))
55