【问题标题】:Bash Shell Scripting: How to Sum the Values in a File With the Use of For Loop and bc Command [duplicate]Bash Shell 脚本:如何使用 For 循环和 bc 命令对文件中的值求和 [重复]
【发布时间】:2018-05-20 23:50:18
【问题描述】:

我目前正在尝试在我的 bash 脚本中编写一个函数,该函数执行以下操作:将文件作为参数并计算该文件中数字的总和。我必须使用 for 循环和 bc 命令。

文件中的值示例(每个值单独一行):

12
4
53
19
6

这就是我目前所拥有的:

function sum_values() {
  for line in $1; do
  #not sure how to sum the values using bc
  done
}

我在正确的轨道上吗?我不确定在这种情况下如何实现 bc 命令。

【问题讨论】:

  • 请参阅BashFAQ #1 了解最佳实践:逐行处理流。另外,请注意,无论是谁给你布置作业,都是在指导你使用不良做法:for loops should not be used to iterate over line-oriented content.
  • ...好吧,除非您先将面向行的内容读入数组;例如:readarray -t values <file 会将您的值放入一个名为 values 的数组中,您可以使用 for value in "${values[@]}"; do echo "processing $value"; done 形式的东西对其进行迭代。
  • ...顺便说一句,使用function 关键字并不是特别好的形式——它使您的代码与/bin/sh 的基线POSIX 实现不兼容,但是——不像更有用的bashisms——不为这种不兼容性增加任何价值; POSIX 函数声明只是 sum_values() {,前面没有 function
  • @CharlesDuffy heh :),不要忘记,大多数教授 bash 的老师不会理解本网站中好的 bash 答案的一半......所以......

标签: linux bash shell unix


【解决方案1】:

无需 for 循环即可轻松完成。

paste -s -d+ numbers.txt | bc

【讨论】:

    【解决方案2】:

    没有在正轨上。为什么?

    • 您将整个文件内容作为变量传递,这需要将整个文件存储在内存中。 123 的例子没有问题,在现实生活中大行其道。
    • 您正在使用for in 循环迭代文件的内容,假设您正在迭代该文件的。这不是真的,因为将执行分词,这使得 for in 循环逐字逐句地迭代 words,而不是 lines
    • 正如其他人所提到的,shell 不是适合它的工具。这是因为与例如awk 相比,shell 的这种处理非常慢。此外,shell 无法执行浮点运算,这意味着您只能处理整数。使用awk

    正确的是(使用 bash,出于教育目的):

    # Expects a filename
    sum() {
        filename=${1}
        s=0
        while read -r line ; do
            # Arithmetic expansion
            s=$((s+line))
            # Or with bc
            # s=$(bc <<< "${s}+${line}")
            # With floating point support
            # s=$(bc -l <<< "${s}+${line}")
        done < "${filename}"
        echo "${s}"
    }
    
    sum filename
    

    awk:

    awk '{s+=$0}END{print s}' filename
    

    【讨论】:

    • 也许指出,除了简洁之外,Awk 解决方案更好,因为它也可以处理浮点数。
    • 非常好!我也忘记了 OP 想要使用 bc 进行计算。刚醒来。稍后会更改。
    【解决方案3】:

    虽然awk(或其他更高级别的语言:perlpython 等)更适合这项任务,但您以天真的方式做这件事是正确的。提示:

    $ x=1
    $ y=$(bc <<<"$x + 1")
    $ echo $y
    2
    

    【讨论】:

      【解决方案4】:

      要在 bash 中进行数学运算,我们将一个操作括在 $(( ... )) 中

      这里有一些例子:

      $(( 5 + 5 )) # 10
      
      my_var = $((5 + 5)) # my_var is now 10
      
      my_var = $(($my_var + 5)) # my_var is now 10
      

      解决您的问题:

      function sum_values() {
          sum=0
          for i in $(<$1); do
              sum=$(($sum + $i))
          done
          echo $sum
      }
      

      请注意,您也可以在上述解决方案中使用 $(cat $1) 而不是 $(

      编辑:将 return $sum 替换为 echo $sum

      【讨论】:

      • 返回$sumsum=-1sum=256 等呢?那真的行不通。
      • @PesaThe 不完全确定您在说什么,但我正在从函数返回 sum 的值
      • 返回状态的值限制为 0 - 255。如果总和是不在此范围内的数字,则您的脚本将出现异常。
      • @PesaThe 啊哈,好收获!我不知道。
      • 因此您可以将return 替换为echo ;-)。祝大家好运。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2011-01-20
      相关资源
      最近更新 更多