Shell 数值计算完全指南:从整数运算到小数精度,一篇搞定

Shell 变量的数值计算实践详解

涵盖整数运算、小数计算、bc/awk 工具及九九乘法表实战,适合 Linux 运维与开发人员。


一、算术运算符概述

和其他编程语言类似,Shell 也支持丰富的算术运算符,用于执行数值计算和逻辑比较。

1.1 常用算术运算符

运算符含义示例
+ -一元正号/负号-5
+ -加 / 减3 + 4
* / %乘 / 除 / 取模(取余)10 / 310 % 3
**幂运算2 ** 3 = 8
++ --自增 / 自减(前置/后置)i++++i
! && ``
< <= > >=比较运算符((5 > 3))
== != =相等 / 不等 / 赋值((a == b))
<< >>左移 / 右移位运算((1 << 3)) = 8
& ` ^` `~`按位与 / 或 / 异或 / 取反
= += -= *= /= %=赋值运算符((a += 3)) 等价于 a = a + 3

1.2 Shell 中常用的算术运算命令

命令说明适用场景
$((...))((...))推荐,高效灵活,用于整数运算日常脚本首选
let((...)) 等价老脚本中常见
expr整数运算,需注意空格和转义较古老,不推荐新脚本
bcLinux 计算器,支持整数 + 小数需要小数运算时
awk文本处理工具,支持小数运算配合文本处理或复杂表达式
$[...]旧语法,已被 $((...)) 取代看懂即可,不推荐使用
declare -i声明整型变量特殊场景

二、((...)) 双小括号 – 最推荐的整数运算方式

双小括号 ((...)) 是 Bash 内置的算术运算语法,效率高、写法简洁,是企业运维脚本中最常用的方式。

2.1 基本用法

用法说明
((i = i + 1))运算后赋值给变量
echo $((1 + 2))$ 取值并输出
i=$((i + 1))将运算结果赋值给变量
((8 > 7 && 5 == 5))支持逻辑比较,用于条件判断

2.2 简单数值计算示例

bash

# 直接输出计算结果
echo $((1 + 1))          # 2
echo $((6 * 3))          # 18

# 给变量赋值
((i = 5))
((i = i * 2))
echo $i                  # 10

# 计算 1+2+...+100
a=$((100 * (100 + 1) / 2))
echo $a                  # 5050

2.3 复杂表达式

bash

((a = 1 + 2 * 3 - 4 % 3))
echo $a                  # 8

# 也可以在一行内完成赋值并取值
b=$((a = 1 + 2 * 3 - 4 % 3))
echo $b                  # 8

# 直接输出表达式的值
echo $((1 + 2 * 3 - 4 % 3))   # 8

优先级说明: **(幂) > * / % > + -,与 C 语言一致。

2.4 比较与条件判断

((...)) 作为命令时,根据表达式的真假返回退出码:

  • 表达式为真 → 返回 0(Shell 中的 true)
  • 表达式为假 → 返回 1(Shell 中的 false)

bash

# 3 < 8 成立,返回 0
((3 < 8))
echo $?                  # 0

# 3 > 8 不成立,返回 1
((3 > 8))
echo $?                  # 1

# 与 if 结合使用
if ((8 > 7 && 5 == 5)); then
    echo yes             # 输出 yes
fi

2.5 自增/自减运算符(前置与后置的区别)

基本概念
  • a++(后置自增):先返回变量当前值,再将变量 +1
  • ++a(前置自增):先将变量 +1,再返回新值
  • a----a 同理(自减)
实战演示

bash

a=10

# 后置自增:先返回 10,再让 a 变成 11
echo $((a++))            # 输出 10
echo $a                  # 输出 11

# 前置自减:先让 a-1 变成 10,再返回 10
echo $((--a))            # 输出 10
echo $a                  # 输出 10
性能提示(理解即可)
  • i++ 需要临时保存 i 的原值再返回,会开辟临时空间。
  • ++i 直接在变量内存上操作并返回,性能略高(微秒级差异,普通脚本无需纠结)。
总结口诀
表达式执行顺序示例(a=10)
echo $((a++))先返回 a,后 a+1输出 10,a 变成 11
echo $((a--))先返回 a,后 a-1输出 10,a 变成 9
echo $((++a))先 a+1,再返回新值输出 11,a 变成 11
echo $((--a))先 a-1,再返回新值输出 9,a 变成 9

2.6 ((...))$((...)) 的区别

用法功能示例
((表达式))执行运算或比较,不输出结果,主要用于赋值或条件判断((a = 5 + 3))
$((表达式))返回表达式的值,用于输出或赋值给其他变量b=$((5 + 3))

bash

num=99
echo $((num + 1))        # 输出 100,num 不变
num=$((num + 1))         # num 变成 100
echo $num                # 100

三、let 命令

let 的功能与 ((...)) 基本等价,写法略有不同,在老脚本中较常见。

bash

i=2
let i=i+8
echo $i                  # 10

# 等价于
((i = i + 8))

建议: 新脚本优先使用 ((...)),写法更自然、更统一。


四、expr 命令(较古老,了解即可)

expr 是早期 Shell 中常用的整数运算工具,使用时必须注意运算符两侧有空格,乘号需要转义。

bash

expr 3 + 4               # 7
expr 3 \* 4              # 12(乘号必须转义)
expr 10 / 3              # 3(整数除法,截断小数)
expr 10 % 3              # 1

缺点:

  • 只支持整数
  • 运算符必须加空格,容易出错
  • 乘号 * 必须转义

建议: 新脚本中直接使用 ((...)) 替代,无需再用 expr


五、bc 命令 – 支持小数运算的计算器

bc 是 Linux 下的高精度计算器,支持整数和小数运算,是 Shell 中处理浮点数的最佳工具。

5.1 基本语法

bash

echo "表达式" | bc
echo "scale=N; 表达式" | bc   # scale 设置小数位数(仅对除法生效)

5.2 bc 常用运算符

符号含义
+ - * /加减乘除
%取模(取余)
^幂运算
scale=N设置除法保留 N 位小数

5.3 实战示例

bash

# 整数运算
echo '1 + 3 * 4 - 6 / 3 * 3 % 4' | bc   # 13

# 小数除法(不设置 scale 时,小数部分被截断)
echo '1/3' | bc            # 0

# 设置 scale=4,保留 4 位小数
echo 'scale=4; 1/3' | bc   # .3333

# 幂运算
echo '2^10' | bc           # 1024

scale 的重要说明:

  • scale 只对除法生效,不影响乘法、加减、幂运算。
  • 不设置 scale 时,除法结果为整数(直接截断,不四舍五入)。

5.4 高级用法:生成并计算序列

计算 1+2+3+...+10 的值:

bash

seq -s + 10 | bc           # 55

拆解:

  • seq 10 → 生成 1 2 3 … 10
  • -s + → 指定分隔符为 +
  • 最终得到字符串 1+2+3+4+5+6+7+8+9+10,通过管道传给 bc 计算。

六、awk 命令 – 强大的文本与数值计算

awk 不仅可以处理文本,也能进行精确的小数运算,非常适合在命令行中快速计算。

bash

# 减法
echo 7.7 3.8 | awk '{print $1 - $2}'   # 3.9

# 复杂表达式
echo 358 113 | awk '{print ($1 - 3) / $2}'   # 3.14159

awk 的数值计算能力很强,适合在文本处理流程中顺便完成运算。


七、$[...] – 过时的整数运算语法

bash

echo $[4 - 2]            # 2
echo $[2 * 2]            # 4
echo $[5 / 2]            # 2(整数除法)
echo $[5 % 2]            # 1

注意: $[...] 是旧版 Bash 兼容语法,在新脚本中应使用 $((...)) 替代。只需看懂老脚本即可。


八、综合实战:九九乘法表(两种写法)

方式一:使用 $((...))

bash

#!/bin/bash
for ((i=1; i<=9; i++)); do
    for ((j=1; j<=i; j++)); do
        temp=$((i * j))
        echo -n "$i*$j=$temp "
    done
    echo
done

方式二:使用 let

bash

#!/bin/bash
for ((i=1; i<=9; i++)); do
    for ((j=1; j<=i; j++)); do
        let "temp = i * j"
        echo -n "$i*$j=$temp "
    done
    printf "\n"
done

运行效果(部分):

text

1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
...
9*1=9 9*2=18 9*3=27 ... 9*9=81

九、各运算工具对比与选择建议

工具支持小数语法简洁度推荐场景
$((...))⭐⭐⭐⭐⭐日常整数运算(首选)
let⭐⭐⭐⭐((...)) 等价,老脚本中常见
expr⭐⭐了解即可,新脚本不建议使用
bc⭐⭐⭐⭐需要小数运算时
awk⭐⭐⭐文本处理中顺便计算
$[...]⭐⭐⭐过时语法,只需看懂

十、总结速记

  • 整数运算优先用 $((...)):高效、简洁、兼容性好。
  • 小数运算用 bcecho "scale=2; 10/3" | bc
  • ((...)) 做判断:真返回 0,假返回 1,与 if 配合完美。
  • 自增自减a++ 先返回后自增,++a 先自增后返回。
  • 九九乘法表:循环嵌套 + $((i * j))let,练手必备。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值