【问题标题】:Arithmetic expressions in Bash?Bash 中的算术表达式?
【发布时间】:2011-01-31 20:13:36
【问题描述】:

我曾使用几种方法在 BASH (3.2) 中进行一些简单的整数运算。但我想不出最好的(首选)方法。

result=`expr 1 + 2`
result=$(( 1 + 2 ))
let "result = 1 + 2"

这些表达式之间的根本区别是什么?
还有其他方法可以做到这一点吗?

浮点运算是否必须使用bc 之类的工具?

result=`echo "7/354" | bc`

【问题讨论】:

    标签: bash floating-point math expression


    【解决方案1】:

    在 Bash 中,let 允许在一行中进行多个赋值:

    let a=3 b=4 c=5
    

    正如您在问题中显示的那样,引用 let 的参数允许您在运算符周围放置空格。但是,如果您避免使用空格,则可以省略引号。

    在语句开头使用双括号的另一种形式(而不是 i=$((j + 1)) 形式)允许您在等号周围包含空格或执行后置或前置递增或递减以及额外的赋值操作:

    (( a = ( b + c ) * 4 ))
    (( count++ ))
    (( d = --c**2 ))
    (( e *= 2 ))
    (( f = 3, g = 5 ))    # multiple operations require a comma separator
    

    如果您使用help "((",则表示双括号“等效于“let EXPRESSION”。”

    您可以使用 declare 内置函数进行赋值,包括间接赋值:

    blue=2
    name=blue
    declare $name=4
    echo $blue    # result: 4
    echo ${!name} # result: 4
    

    编辑:

    $(()) 构造被称为“arithmetic expansion”,它使内容被计算为一个整数表达式。它是 shell 的一个语法元素。

    如果变量声明为整数,则不需要使用任何一种形式的双括号,您可以在变量名中省略美元符号(如双括号形式),但不能添加运算符周围的空格:

    declare -i x=1   # set integer, initialize to 1
    declare +i s=1   # clear integer, initialize to 1
    x+=1             # could also be x=x+1
    echo $x          # result: 2 (addition)
    s+=1             # could also be s=$s+1, requires a "$"
    echo $s          # result: 11 (string concatenation)
    

    与上面的表格不同,调用expr 涉及生成一个外部可执行文件,这对于循环中的大量计算可能非常昂贵。 唯一 应该使用它的时间是在 shell 无法进行自己的算术运算的环境中,或者当脚本可能会进入这样的环境时的可移植性。 POSIX shell 具有算术能力,因此只有旧系统才需要考虑。

    关于使用bc 进行浮点运算,在使用 Bash 和许多其他 shell 时需要它或类似的东西。 POSIX 说“只需要有符号长整数运算。”

    支持浮点数学的两个 shell 是 ksh 和 zsh。除了 bc,您还可以在 Bash 脚本中使用 dc、AWK、Python、Perl 等。

    Bash 对浮点数做的一件事是使用内置的 printf 打印它们(请注意,还有一个外部的 printf,但内置有优先级)。

    printf "%'14.4f\n" 1234.56  # result "    1,234.5600" (in my locale)
    

    【讨论】:

    • 您未能讨论生成 expr 等的含义以及 $(()) 是否是 bultin。
    • @Vlad:我希望你发现添加的内容有所改进。
    【解决方案2】:

    我更喜欢您的第二个选项,因为它不需要外部实用程序:

    result=$(( 1 + 2 ))
    

    第一个选项调用 expr 来计算 - 我不熟悉 letbc 的另一种替代方法是 dc。选择你最喜欢的。

    【讨论】:

      【解决方案3】:

      我不能说它是“强制性的”,但bc 可能是您进行通用算术的最佳选择。

      对于更高级的东西,您总是可以通过 Perl 进行管道传输。

      这两种方法的缺点是它们都打开了一个子进程,因此在紧密循环中执行它会比本机 bash 表达式慢(在您的第一个示例中,使用反引号会出现同样的问题)。我不确定$(()) 是否调用了子进程。

      【讨论】:

        【解决方案4】:

        Is the use of a tool like bc mandatory for floating point arithmetic?

        不,如果您使用的是支持浮点的 shell,例如 zsh、ksh。否则,如果您想进行更高级的浮点数学运算,请使用其中之一,bc/awk/dc。当然,Perl/Python 等也是如此。

        【讨论】:

          【解决方案5】:

          您拥有的第三个选项的可读性要差得多,因为它看起来不像赋值运算符。正如其他人所指出的,第一个调用外部命令

          【讨论】:

            猜你喜欢
            • 2011-01-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-20
            • 2015-10-27
            • 2015-09-01
            • 1970-01-01
            • 2015-07-02
            相关资源
            最近更新 更多