在Linux Shell中使用变量进行除法
1. 概述
Bash中有几个用于执行除法的命令和实用程序。除了它们,我们还可以使用 Linux 发行版中可用的脚本语言。
在本教程中,我们将介绍 Bash 中的以下除法选项:
- expr、let和printf命令
- 双括号复合命令
- 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
我们可以看到结果是一个整数,就像expr和let命令的输出一样。因此,分子和分母也必须是整数,不能是浮点数:
$ 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命令可以是指向python2或python3命令的软链接。让我们对两个 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