楼主: Vicky017
56 0

[教育经济学基本知识] 5.Shell 数值计算实践 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-8-4
最后登录
2018-8-4

楼主
Vicky017 发表于 2025-12-5 19:54:22 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

5. 变量的数值计算实践

5.1 常见的 Shell 算术运算符

在进行算术运算时,需要使用各种运算符号。Shell 支持丰富的算术运算符,与其他编程语言类似,能够满足多种数学和逻辑操作需求。

  • +、-:作为一元运算符时表示正号或负号;作为二元运算符时表示加法与减法。
  • *、/、%:分别代表乘法、除法以及取余(也称取模)操作。
  • **:用于执行幂运算,例如 2 的 3 次方可表示为 2**3。
  • ++、--:自增与自减运算符,可用于变量前(前置)或后(后置)。
  • !、&&、||:逻辑非(取反)、逻辑与(and)、逻辑或(or),常用于条件判断中。
  • <、<=、>、>=:比较运算符,表示小于、小于等于、大于、大于等于。
  • ==、!=、=:用于判断相等或不相等,其中 = 在字符串比较中也可表示“相当于”。
  • <<、>>:位移运算符,分别表示向左移位和向右移位。
  • ~、|、&、^:按位取反、按位或、按位与、按位异或。
  • =、+=、-=、*=、/=、%=:赋值及复合赋值运算符。例如:
    a+=1

    相当于
    a=a+1


    a-=1

    相当于
    a=a-1

常用的 Shell 算术运算命令

除了基本运算符外,Shell 还提供了多个可用于数值计算的命令:

  • (()):主要用于整数运算,执行效率高,是运维中常用的方式。
  • let:实现整数运算,功能上类似于(())
    (())
  • expr:支持整数运算,同时具备其他文本处理能力。
  • bc:Linux 下的功能强大计算器程序,适用于整数和小数运算。
  • $[]:旧式整数运算语法,现已逐渐被$((...))替代。
  • awk:既能处理整数也能处理浮点数运算,适合复杂场景。
  • declare:用于定义变量属性,通过 -i 参数可声明整型变量并直接参与运算。

5.2 使用 (()) 双小括号进行数值运算

双小括号 (()) 是 Shell 中非常高效的数值运算工具,不仅可以进行数学计算,还能完成数值比较和逻辑判断,广泛应用于脚本开发和系统管理任务中。

5.2.1 (()) 的基础语法结构

以下是 (()) 的常见用法:

  • ((i = i + 1)):将表达式 i+1 的结果重新赋值给变量 i,属于典型的“先运算后赋值”模式。
  • 注意:不能直接使用 echo (i+1) 输出表达式的值,而应使用带美元符号的形式:
    echo ((i=i+l))

    正确的写法是:
    echo $((i=i+l))
  • 可以在 (()) 前添加 $ 符号,如:
    $((i+1)),表示对该表达式求值并返回结果。
  • ((8 > 7 && 5 == 5)):支持复杂的条件判断,包含关系比较与逻辑运算(与、或)。
  • 若需直接输出表达式结果,可使用:
    echo $((2+1)),即在 (()) 外包裹 $() 实现结果输出。

5.2.2 (()) 数值运算的实际应用示例

示例1:简单数值计算

[root@server ~ 15:53:03]# echo $((1+1))
2
[root@server ~ 16:05:57]# echo $((6*3))
18
[root@server ~ 16:06:11]# ((i=5))
[root@server ~ 16:06:29]# ((i=i*2))
[root@server ~ 16:06:41]# echo $i
10

示例2:复杂表达式运算

[root@server ~ 16:06:48]# ((a=1+2**3-4%3))
[root@server ~ 16:07:22]# echo $a
8
[root@server ~ 16:51:45]# b=$((a=1+2**3-4%3))
[root@server ~ 18:25:06]# echo $b
8
[root@server ~ 18:25:13]# echo $((a=1+2**3-4%3))
8
[root@server ~ 18:25:20]# a=$((100*(100+1)/2))
[root@server ~ 18:25:34]# echo $a
5050
[root@server ~ 18:25:40]# echo $((100*(100+1)/2))
5050

示例3:特殊运算符的使用

[root@server ~ 18:25:47]# a=8;echo $((a+=1))
9
[root@server ~ 18:26:01]# echo $((a**2))
81

示例4:比较与逻辑判断

[root@server ~ 16:07:27]# ((3<8))
[root@server ~ 16:07:49]# echo $?
0
[root@server ~ 16:07:53]# echo $((3<8))
1
[root@server ~ 18:26:07]# ((3>8))
[root@server ~ 18:26:28]# echo $?
1
[root@server ~ 18:26:34]# echo $((3>8))
0

说明:在 (()) 中进行比较时,若条件成立则退出状态 $? 为 0(真),否则为 1(假);而使用 echo $((...)) 输出时,结果以 1 表示真,0 表示假。

[root@server ~ 18:26:41]# echo $((3==3))
1
[root@server ~ 18:26:47]# if ((8>7 && 5==5));then echo yes;fi
yes

示例5:使用 ++ 和 -- 运算符对变量进行操作的表达式

在 Shell 中,前置与后置自增、自减运算符会影响表达式的输出结果。

[root@server ~ 16:08:33]# a=10
[root@server ~ 16:08:52]# echo $((a++))
10
[root@server ~ 16:09:03]# echo $a
11
[root@server ~ 16:09:08]# echo $((--a))
10
[root@server ~ 16:09:25]# echo $a
10

总结如下:

  • 执行 echo $((a++))echo $((a--)) 时,先输出表达式的值,该值为变量当前的原始值;
    echo $((a++))
  • 随后再对变量进行自增或自减操作。
    echo $((a--))
  • 也就是说,在输出整个表达式的时候,显示的是 a 的初始值(即
    a
    的值),而运算完成后,会对 a 执行
    ++
    --
    操作。
  • 当执行 echo $((++a))echo $((--a)) 时,系统会首先对变量 a 进行
    ++
    --
    操作;
    echo $((++a))
  • 然后才计算并输出表达式的值,因此最终输出的是经过运算之后的新值。
    echo $((--a))

示例6:利用 (()) 运算并将结果赋值给变量

可以通过双括号结构完成算术运算,并将结果重新赋值给原变量或其他变量。

[root@server ~ 18:26:57]# num=99
[root@server ~ 18:27:24]# echo $((num+1))
100
[root@server ~ 18:29:06]# num=$((num+1))
[root@server ~ 18:29:16]# echo $num
100

5.3 let 命令

let 命令用于执行算术表达式,其语法格式如下:

let 表达式

其功能等价于使用 $((...)) 结构进行运算。

((表达式))

实际应用示例:

[root@server ~ 16:09:27]# i=2
[root@server ~ 16:09:49]# i=i+8
[root@server ~ 16:09:56]# echo $i
i+8

直接写 i=i+8 并不会执行数学运算,而是将其视为字符串赋值。

[root@server ~ 16:10:15]# i=2
[root@server ~ 16:10:19]# let i=i+8
[root@server ~ 16:10:21]# echo $i
10

使用 let 后,表达式被正确解析为算术运算,变量 i 成功更新为 10。

5.4 expr 命令

expr 不仅支持整数算术运算,还可用于字符串处理,如长度判断、模式匹配等场景。

expr(evaluate(求值)expressions(表达式))

5.4.1 expr 基本用法示例

[root@server ~ 16:10:25]# expr 2 + 2
4
[root@server ~ 16:10:58]# expr 2 \* 2
4

使用 expr 时需注意以下规则:

  • 运算符和数字两侧必须至少有一个空格,否则会导致语法错误。
  • 乘法符号 * 必须通过反斜杠转义(写作 \*),以避免 shell 将其解释为通配符。
    expr

expr 命令退出码说明:

退出码 含义
0 表达式计算成功(例如:expr 2 + 3)
1 表达式结果为空或为 "0"(例如:expr 0)
2 参数非法,如包含非整数参与运算
3 表达式存在语法错误(如缺少操作数)

5.4.2 expr 企业级实战案例详解

示例1:判断变量内容是否为整数

由于 Shell 缺乏内置类型检测函数,判断一个值是否为整数通常需要借助外部命令。这里介绍一种基于 expr 特性的方法。

实现原理:
利用 expr 在进行数值运算时要求所有操作数必须为整数的特性。将待测变量与一个已知整数相加,若返回退出码为 0,则说明变量是合法整数;若返回退出码为 2,则表示参数不合法,即不是整数。

[root@server ~ 16:11:12]# i=5
[root@server ~ 16:11:48]# expr $i + 5
10
[root@server ~ 16:11:55]# echo $?
0
[root@server ~ 16:12:03]# i=a
[root@server ~ 16:12:34]# expr $i + 5
expr: non-integer argument
[root@server ~ 16:12:37]# echo $?
2

上述输出中,“non-integer argument” 表示传入了非整数参数,本质是“非整数参与了算术运算”,这是 expr 对非法参数的标准反馈,对应退出码为 2。

此外,expr match 可用于正则表达式匹配,返回匹配到的字符个数:

  • 匹配成功 → 返回匹配部分的字符长度;
  • 匹配失败 → 返回 0。

可通过执行 expr --help 或查阅手册获取更多帮助信息。

man expr

# 变量值为非整数,返回值为0
[root@server ~ 16:14:41]# i=a
[root@server ~ 16:16:28]# expr match "$i" "^[1-9][0-9]*$"
0

# 变量值为整数,返回值大于0
[root@server ~ 16:16:28]# i=123
[root@server ~ 16:16:30]# expr match "$i" "^[1-9][0-9]*$"
3

示例1:使用 expr 判断变量是否为正整数

[root@server ~ 16:17:00]# i=5
[root@server ~ 16:18:28]# expr match "$i" "^[1-9][0-9]*$"
1

示例2:验证文件扩展名是否符合指定格式

[root@server ~ 16:18:29]# file=stu-202212.jpg
# 检查是否以 .jpg 结尾,返回匹配长度(14),不关注输出值
[root@server ~ 16:18:46]# expr "$file" : ".*\.jpg$"
14
[root@server ~ 16:19:01]# echo $?
# 尝试匹配 .pub 扩展名,未匹配成功,返回0
[root@server ~ 16:19:08]# expr "$file" : ".*\.pub$"
[root@server ~ 16:19:39]# echo $?
1

示例3:计算字符串的字符数量

[root@server ~ 16:19:41]# str="abc123abc123"
[root@server ~ 16:20:04]# expr length "$str"
12

示例4:筛选出语句中长度不超过6个字符的单词

[root@server ~ 16:21:01]# vim str.sh
[root@server ~ 16:21:20]# cat str.sh
#!/bin/bash
strings="This is Linux World  Welcome to our classroom"
for word in $strings
do
if [ $(expr length "$word") -le 6 ];then
echo $word
fi
done

脚本执行后的输出结果如下:

[root@server ~ 16:21:23]# bash str.sh
This
is
Linux
World
to
our

5.5 bc 命令

bc 是类 UNIX 系统下的高精度计算器工具,既可交互使用,也可在命令行中作为数学运算处理器。

bc

使用示例:

[root@server ~ 16:21:43]# 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'.
4/7
scale=3
4/7
.571
quit

通过管道传递表达式进行非交互式计算:

[root@server ~ 16:23:42]# echo '4/8' |bc
.5
[root@server ~ 16:23:53]# echo 'scale=1;4/8' |bc
.5
[root@server ~ 16:22:31]# echo 'scale=3;4/8' |bc
.500

5.6 使用 awk 命令进行数值计算

awk 支持整数和小数运算,特别适合在命令行中处理浮点数,计算精度高,操作简便。

[root@server ~ 16:24:01]# echo 7.7 3.8 | awk '{ print $1-$2 }'
3.9
[root@server ~ 16:24:25]# echo 358 113 | awk '{ print ($1-3)/$2 }'
3.14159

5.7 使用 $[] 符号进行算术运算

示例1:基本四则运算与自增自减操作

[root@server ~ 18:29:22]# echo $[1+1]
2
[root@server ~ 18:29:22]# echo $[4-2]
2
[root@server ~ 18:29:22]# echo $[2*2]
4
[root@server ~ 18:29:22]# echo $[4/2]
2
[root@server ~ 18:29:22]# echo $[5/2]
2
[root@server ~ 18:29:22]# echo $[5%2]
1
[root@server ~ 18:29:22]# count=3;echo $[(count+1)*3]
12
[root@server ~ 18:29:22]# count=3;echo $[ ++count + 3 ]
7
[root@server ~ 18:29:22]# count=3;echo $[ count++ + 3 ]
6
[root@server ~ 18:29:22]# count=3;echo $[ --count + 3 ]
5
[root@server ~ 18:29:22]# count=3;echo $[ count-- + 3 ]
6

示例2:利用单条命令完成复杂表达式的求值任务,推荐使用 bc 工具实现精确计算。最终输出结果如图所示:

1+2+3+...+10
1+2+3+4+5+6+7+8+9+10=55
[root@server ~ 18:29:22]# echo $(seq -s + 10) | bc
55
[root@server ~ 18:29:22]# echo $(( $(echo {1..10} | tr ' ' '+' ) ))
55
[root@server ~ 18:29:22]# echo $[ $(echo {1..10} | tr ' ' '+' ) ]
55
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Shell 数值计算 Shel SHE expressions

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2026-1-2 03:00