关于linux:Bash Shell Scripting:如何使用For循环和bc命令对文件中的值求和

Bash Shell Scripting: How to Sum the Values in a File With the Use of For Loop and bc Command

本问题已经有最佳答案,请猛点这里访问。

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

文件中的值示例(每一个值在其自己的行上):

1
2
3
4
5
12
4
53
19
6

这是我到目前为止所拥有的:

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

我走对了吗?我不知道如何在这种情况下实现BC命令。


不需要for循环就可以轻松完成。

1
paste -s -d+ numbers.txt | bc

你不在正轨上。为什么?

  • 您正在将整个文件内容作为变量传递,该变量要求将整个文件存储在内存中。一个123的例子没有问题,在现实生活中没有什么大不了的。
  • 您正在使用for in循环迭代文件的内容,假设您正在迭代该文件的行。这不是真的,因为将执行分词操作,这使得for in循环在单词而不是行上逐字迭代。
  • 正如其他人提到的,shell不是合适的工具。这是因为与awk相比,这种处理对于shell来说非常慢。此外,shell不能执行浮点操作,这意味着您只能处理整数。使用awk

正确的做法是(对于bash,出于教育目的):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 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时:

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


为了在bash中进行数学运算,我们用$(…)包围了一个操作。

以下是一些例子:

1
2
3
4
5
$(( 5 + 5 )) # 10

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

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

解决问题的方法:

1
2
3
4
5
6
7
function sum_values() {
    sum=0
    for i in $(<$1); do
        sum=$(($sum + $i))
    done
    echo $sum
}

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

编辑:将返回$sum替换为echo$sum


虽然awk(或其他更高级的语言:perlpython等)更适合这项任务,但你做这项工作的方式是幼稚的。提示:

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