shell 数学运算

1. 数学运算

对任何编程语言都很重要的特性是操作数字的能力。遗憾的是,对shell脚本来说,这个处理过程会比较麻烦。在shell脚本中有两种途径来进行数学运算。

2. expr 命令

最开始,Bourne shell提供了一个特别的命令用来处理数学表达式。 expr 命令允许在命令行上处理数学表达式,但是使用很不方便。

owon@mark MINGW64 /c/Users/lyj/Desktop
$ expr 1 + 5
6

2.1 expr 命令操作符

操作符                      描 述
-------------------------+---------------------------------------------------------------------
ARG1 | ARG2              | 如果 ARG1 既不是null也不是零值,返回 ARG1 ;否则返回 ARG2
ARG1 & ARG2              | 如果没有参数是null或零值,返回 ARG1 ;否则返回 0
ARG1 < ARG2              | 如果 ARG1 小于 ARG2 ,返回 1 ;否则返回 0
ARG1 <= ARG2             | 如果 ARG1 小于或等于 ARG2 ,返回 1 ;否则返回 0
ARG1 = ARG2              | 如果 ARG1 等于 ARG2 ,返回 1 ;否则返回 0
ARG1 != ARG2             | 如果 ARG1 不等于 ARG2 ,返回 1 ;否则返回 0
ARG1 >= ARG2             | 如果 ARG1 大于或等于 ARG2 ,返回 1 ;否则返回 0
ARG1 > ARG2              | 如果 ARG1 大于 ARG2 ,返回 1 ;否则返回 0
ARG1 + ARG2              | 返回 ARG1 和 ARG2 的算术运算和
ARG1 - ARG2              | 返回 ARG1 和 ARG2 的算术运算差
ARG1 * ARG2              | 返回 ARG1 和 ARG2 的算术乘积
ARG1 / ARG2              | 返回 ARG1 被 ARG2 除的算术商
ARG1 % ARG2              | 返回 ARG1 被 ARG2 除的算术余数
STRING : REGEXP          | 如果 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配
match STRING REGEXP      | 如果 REGEXP 匹配到了 STRING 中的某个模式,返回该模式匹配
substr STRING POS LENGTH | 返回起始位置为 POS (从 1 开始计数)、长度为 LENGTH 个字符的子字符串
index STRING CHARS       | 返回在 STRING 中找到 CHARS 字符串的位置;否则,返回 0
length STRING            | 返回字符串 STRING 的数值长度
+ TOKEN                  | 将 TOKEN 解释成字符串,即使是个关键字
(EXPRESSION)             | 返回 EXPRESSION 的值
-------------------------+--------------------------------------------------------------------

注意: 许多 expr 命令操作符在shell中另有含义(比如星号)。当它们出现在在 expr 命令中时,会得到一些诡异的结果。要解决这个问题,对于那些容易被shell错误解释的字符,在它们传入 expr 命令之前,需要使用shell的转义字符(反斜线)将其标出来。例如这样 $ expr 5 \* 2

2.2. 运算结果赋值变量

在shell脚本中使用 expr 命令很复杂,要将一个数学算式的结果赋给一个变量,需要使用命令替换来获取 expr 命令的输出。

var1=10
var2=20
var3=$(expr $var2 / $var1)
echo The result is $var3
The result is 2

3. 方括号命令

bash shell为了保持跟Bourne shell的兼容而包含了 expr 命令,但它同样也提供了一种更简单的方法来执行数学表达式。在bash中,在将一个数学运算结果赋给某个变量时,可以用美元符和方括号$[ operation ]将数学表达式围起来。

$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12

4. 浮点运算

我们首先来看下面的一个shell的除法运算,可以发现除法得到的小数部分被舍弃。

var1=100
var2=45
var3=$[$var1 / $var2]
echo The final result is $var3
2

bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制。有几种解决方案能够克服bash中数学运算的整数限制。最常见的方案是用内建的bash计算器,叫作 bc 。

4.1. bc 计算器的基本用法

bash计算器实际上是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果。bash计算器能够识别:

  • 数字(整数和浮点数)
  • 变量(简单变量和数组)
  • 注释(以#或C语言中的 /* */ 开始的行)
  • 表达式
  • 编程语句(例如 if-then 语句)
  • 函数

通过 bc 命令访问bash计算器:

$ 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'.
12 * 5.4
64.8
3.156 * (3 + 5)
25.248
quit # 要退出bash计算器,你必须输入 quit 。
$

内建变量 scale:

浮点运算是由内建变量 scale 控制的。scale 变量的默认值是 0,必须将这个值设置为你希望在计算结果中保留的小数位数,否则无法得到期望的结果。例如下面这样。

$ bc -q
3.44 / 5
0
scale=4
3.44 / 5
.6880
quit

4.2. 在脚本中使用 bc

现在你可能想问bash计算器是如何在shell脚本中帮助处理浮点运算的。可以用命令替换运行 bc 命令,并将输出赋给一个变量。基本格式如 variable=$(echo "options; expression" | bc)。第一部分 options 允许你设置变量。如果你需要不止一个变量,可以用分号将其分开,例如下面这样。

var1=$(echo "scale=4; 3.44 / 5" | bc)
echo The answer is $var1
The answer is .6880

上面这个方法适用于较短的运算,但有时你会涉及更多的数字。如果需要进行大量运算,在一个命令行中列出多个表达式就会有点麻烦。比如下面的例子。

var1=20
var2=3.14159
var3=$(echo "scale=4; $var1 * $var1" | bc)
var4=$(echo "scale=4; $var3 * $var2" | bc)
echo The final result is $var4

有一个方法可以解决这个问题。 bc 命令能识别输入重定向,允许你将一个文件重定向到 bc命令来处理。但这同样会叫人头疼,因为你还得将表达式存放到文件中。最好的办法是使用内联输入重定向,它允许你直接在命令行中重定向数据。在shell脚本中,你可以将输出赋给一个变量。EOF 文本字符串标识了内联重定向数据的起止。记住,仍然需要命令替换符号将 bc 命令的输出赋给变量。

variable=$(bc << EOF
options
statements
expressions
EOF
)

使用方式:

var1=10.46
var2=43.67
var3=33.2
var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
The final answer for this mess is 2813.9882
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值