【问题标题】:arithmatic operation in shell scriptshell脚本中的算术运算
【发布时间】:2019-12-16 06:02:30
【问题描述】:

我的 shell 脚本是这样的,

sOneCount =5
sZeroCount=12
aa=`expr $sOneCount / $sZeroCount`
successRate=`expr $aa \* 100

因为 5/12 的结果是 0.416,然后是 0.416*100,它应该给出 41.6 但我将“successRate”设为 0。 它对浮点值进行四舍五入。

我希望最终结果应该是这样的 41, 请帮助我谢谢

【问题讨论】:

  • 是的,awk 将简化此操作。请至少阅读Awk Tutorial -- printf 和下面的格式说明符部分。祝你好运。
  • 您不太可能使用不支持标准 POSIX 算术表达式的 Bourne 风格的 shell。请改用aa=$(( sOneCount / sZeroCount ))successRate=$(( aa * 100 ))expr 已过时,除了正则表达式匹配。 (但更重要的是,大多数 shell 不支持浮点运算;zsh 是一个明显的例外。)
  • 您可以在这里找到相当全面的解决方案列表:stackoverflow.com/questions/12722095/…

标签: linux shell awk programming-pearls


【解决方案1】:

Bash,可能还有其他类似的 shell,不支持浮点运算:

以固定宽度的整数进行计算,不检查溢出

http://man7.org/linux/man-pages/man1/bash.1.html#ARITHMETIC_EVALUATION

您可以改用 bc,启用 mathlib 操作:

$ successRate=$(echo "${sOneCount} / ${sZeroCount} * 100" | bc -l)
$ echo ${successRate}
41.66666666666666666600

【讨论】:

    【解决方案2】:

    您应该使用 awk 而不是 shell 来进行计算(可能还有其他任何您正在做的事情,但我们看不到脚本的其余部分):

    $ cat tst.sh
    #!/bin/env bash
    
    sOneCount=$1
    sZeroCount=$2
    
    awk -v sOneCount="$sOneCount" -v sZeroCount="$sZeroCount" 'BEGIN{
        aa = (sZeroCount == 0 ? 0 : sOneCount / sZeroCount)
        successRate = aa * 100
        print successRate
        printf "%d\n", successRate
    }'
    
    $ ./tst.sh 5 12
    41.6667
    41
    
    $ ./tst.sh 5 0
    0
    0
    

    请注意,它可以防止除以零错误。

    【讨论】:

      【解决方案3】:

      请注意,expr 手册页(1)/ 运算符为您提供 ,这意味着这是仅整数运算。

      你可以通过将分子乘以 100 得到积分成功率first

      $ successRate=$( expr 100 \* "$sOneCount" / "$sZeroCount" )
      $ echo "$successRate"
      41
      

      或者,在 bash 中,您不需要调用 expr -- 使用内置的算术表达式语法:

      $ successRate=$(( 100 * sOneCount / sZeroCount ))
      $ echo "$successRate"
      41
      

      (1):我的 Mac 上的 BSD expr 的手册页更明确:/ 返回“整数值参数”的“整数除法”结果。

      【讨论】:

        【解决方案4】:

        对于大多数基本情况,您可以在awk 中轻松编写自己的计算器/评估

        例如:

        $ eval() { awk "BEGIN {print $1}"; }
        $ x=4; y=7;
        $ eval "$x/$y"
        0.571429
        
        $ rate=$(eval "$x/$y")
        $ eval "$rate*100"
        57.1429
        

        或者,稍加改动可以接受更多参数

        $ eval() { awk "BEGIN {print $*}"; }
        $ eval "$x" / "$y" "*" 100
        57.1429
        

        【讨论】:

          猜你喜欢
          • 2011-03-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-13
          • 2011-07-21
          • 1970-01-01
          • 1970-01-01
          • 2021-09-01
          相关资源
          最近更新 更多