Contents

在Linux Shell中使用变量进行除法

1. 概述

Bash中有几个用于执行除法的命令和实用程序。除了它们,我们还可以使用 Linux 发行版中可用的脚本语言。

在本教程中,我们将介绍 Bash 中的以下除法选项:

  • exprletprintf命令
  • 双括号复合命令
  • bc和awk实用程序
  • Python 和 Perl 编程语言

我们将在所有这些选项中使用除法运算符,即*/* 。

2. 使用expr命令

我们可以用于除法的一个命令是expr 命令:

$ x=60
$ y=-3
$ expr $x / $y
-20

即使结果实际上应该是浮点数,它也会返回一个整数:

$ x=60
$ y=-9
$ expr $x / $y
-6

在这里,我们预计结果约为 -6.67,但小数点和小数点后的数字被截断。这是因为Bash 不支持浮点运算。 此外,expr命令也不能将浮点数作为输入:

$ x=60.0
$ y=-3
$ expr $x / $y
expr: non-integer argument

除法运算符前后的空格很重要

$ x=60
$ y=-3
$ expr $x/$y
60/-3

如我们所见,如果除法运算符前后没有空格,则提供给expr命令的表达式将被计算为字符串。如果我们在除法运算符之前或之后省略空格,则会出现语法错误:

$ expr $x /$y  # No space after /
expr: syntax error: unexpected argument '/-3'
$ expr $x/ $y  # No space before /
expr: syntax error: unexpected argument '-3'

3. 使用let命令

我们也可以使用let 命令进行除法。它需要一个或多个算术运算并评估它们。

让我们使用let命令进行除法:

$ let x=60 y=-9 result=x/y
$ echo $result
-6

我们可以通过使用未在let命令上下文中定义的 shell 变量来执行相同的除法:

$ x=60
$ y=-9
$ let result=$x/$y
$ echo $result
-6

expr命令类似,除法的结果是一个整数。另外,分子和分母必须是整数,不能是浮点数

$ x=10.5
$ y=-2
$ let result=$x/$y
-bash: let: result=10.5/-2: syntax error: invalid arithmetic operator (error token is ".5/-2")

4. 使用双括号复合命令

执行除法的另一种方法是使用双括号复合命令$((…))

$ x=60
$ y=-9
$ echo $(($x / $y))
-6

** expr命令的除法运算符前后存在空格的限制对于双括号复合命令无效**:

$ x=60
$ y=-9
$ echo $(($x/$y))  # No spaces before and after /
-6

我们可以看到结果是一个整数,就像exprlet命令的输出一样。因此,分子和分母也必须是整数,不能是浮点数

$ x=10.5
$ y=-2
$ echo $(($x/$y))
-bash: 10.5/-2: syntax error: invalid arithmetic operator (error token is ".5/-2")

5. 使用printf命令

我们可以用于除法的另一个命令是printf 命令。此命令类似于 C 编程语言中的对应命令。 它将格式规范和参数作为输入,并打印格式化文本作为输出:

$ x=60
$ y=-9
$ printf "%f\n" $((x/y))
-6.000000

“%f\n”是终端打印的格式化文本。这里,%f是格式说明符。它打印相应的参数是一个浮点数。\n用于创建新行。最后,*$((x/y))*是提供给格式说明符的参数。

正如我们已经知道的,最后一次除法中结果的小数部分不正确,因为运算*$((x/y))的结果是 -6。%f格式说明符仅将此整数打印为浮点数,因此我们得到-6.000000*。但是,获得更精确的结果是可能的:

$ printf "%f\n" $((10**6 * x/y))e-6
-6.666666

让我们解释一下我们是如何得到这个结果的。格式说明符之后的参数*$((10**6 * x/y))e-6是从左到右计算的。首先,评估了参数的$((10**6 * x/y))部分。在这里,我们首先将10**6* (1000000) 乘以x。因此我们得到 60000000。然后,我们将它除以y,所以我们得到 -6666666 由于整数除法。此时,我们将 -6666666e-6 作为传递给格式说明符的参数。由于e-6,格式说明符将此数字作为浮点数处理,并将 -6666666 除以 1000000,得到 -6.666666。

因此,使用printf命令获得更精确结果的技巧是以这种通用形式使用它

$ printf "%.<precision>f\n" $((10**<precision> * <numerator>/<denominator>))e-<precision>

这里,*是我们想要的小数点后的位数。是除以的数字。如果*未使用格式说明符指定,则默认为 6。

让我们使用上面的一般形式划分变量,但精度不同:

$ printf "%.4f\n" $((10**4 * x/y))e-4
-6.6666

由于我们将精度指定为4 ,因此打印了*-6.6666*  。默认精度为 6。 分子和分母必须是整数,不能是浮点数

$ x=10.5
$ y=-2
$ printf "%f\n" $((x/y))
-bash: 10.5: syntax error: invalid arithmetic operator (error token is ".5")

6. 使用bc命令

bc 实用程序在执行除法时也很有用。bc代表基本计算器。如果我们在没有任何参数的情况下运行该实用程序,它将以交互模式运行。在这种模式下,我们只需输入除法表达式即可得到结果:

$ bc -q
60/-9
-6

传递给bc命令的*-q*选项只是抑制在交互模式开始时打印的欢迎消息。 我们不能在交互模式下使用 shell 变量。但是,我们可以使用 shell 管道 ( | )在非交互模式下使用它们:

$ x=60
$ y=-9
$ echo "$x / $y" | bc
-6

在这里,shell pipe 操作符将echo命令的输出提供给bc命令的标准输入。

我们可以通过使用特定于bc命令的特殊变量scale来获得浮点数的结果。它的值默认为 0。这就是为什么我们在上面的命令执行的输出中没有小数点。scale决定小数点后的位数。如果我们将其设置为4,我们会得到小数点后的四位数字:

$ echo "scale=4; $x / $y" | bc
-6.6667

分子和分母也可以是浮点数

$ x=10.5
$ y=-2
$ echo "scale=4; $x / $y" | bc
-5.2500

在上述命令中使用双引号至关重要。双引号允许 shell 扩展 shell 变量。但是,如果我们改用单引号,就会出现语法错误。单引号不会让 shell 扩展 shell 变量

$ x=60
$ y=-9
$ echo '$x / $y' | bc
(standard_in)  1: illegal character: $
(standard_in)  1: illegal character: $

7. 使用awk命令

awk 命令是众所周知的文本处理实用程序。它还支持执行算术运算。

我们可以将此支持与它的BEGIN规则一起使用来执行除法。awk命令在处理任何输入之前使用BEGIN规则一次。因此,让我们使用awk命令进行除法:

$ awk 'BEGIN {x=60;y=-9;print x/y}'
-6.66667

从输出中我们可以看出,除法的结果是一个浮点数。在这里,我们在BEGIN规则的操作部分定义了变量x和*y 。*我们也可以使用已经在 shell 中定义的变量,但是我们必须使用双括号:

$ x=60
$ y=-9
$ awk "BEGIN {print $x/$y}"
-6.66667

变量也可以是浮点数

$ x=10.5
$ y=-2
$ awk "BEGIN {print $x/$y}"
-5.25

8. 使用 Python 编程语言

Python 编程语言通常安装在Linux 发行版中。我们可以从命令行执行 Python 语句,而无需编写 Python 脚本。

假设我们的系统中同时安装了 Python2 和 Python3,python命令可以是指向python2python3命令的软链接。让我们对两个 Python 版本进行除法:

$ x=60
$ y=-9
$ python3 -c "print($x/$y)"
-6.666666666666667
$ python2 -c "print($x/$y)"
-6

传递给python2 和python3命令的*-c*选项让我们可以从命令行执行 Python 语句。

Python2 中两个整数相除得到一个整数,但在 Python3 中它可以是浮点数。

可以在 Python3 中设置结果的精度:

$ python3 -c 'x=60; y=-9; print("{:.4f}".format(x/y))'
-6.6667

Python 具有float数据类型,因此除法的输入可以是浮点数

$ python3 -c 'x=10.5; y=-2.0; print("{:.2f}".format(x/y))'
-5.25

9. 使用 Perl 编程语言

Perl在大多数 Linux 发行版中也很容易获得。所以,我们也可以用它来进行除法:

$ x=60
$ y=-9
$ result=$(perl -e "print $x/$y")
$ echo $result
-6.666666666666667

 传递给perl命令的*-e*选项让我们可以从命令行执行 Perl 语句。我们可以设置结果的精度:

$ perl -e '$x=60; $y=-9; printf("%.4f\n", $x/$y)'
-6.6667

由于 Perl 支持浮点数,我们可以对浮点数进行除法

$ x=10.5
$ y= -2
$ result=$(perl -e "print $x/$y")
$ echo $result
-5.25