bash从文件中获取数字并获得它们的平均值

时间:2018-01-26 19:19:33

标签: bash shell scripting

  

编写一个期望文件作为其第一个参数的脚本。一些行   文件将包含整数0 - 1000。   脚本应选择与先前条件匹配的行,并将它们的平均值打印到stdout(n个整数的平均值是它们的总和除以n)。

给出的文件如下:

22
78907
77 88 99 0000
need 11 gallons of water
0
roses are red
11

示例输出:

11

说明:(22 + 11 + 0)/ 3 = 11

我已尝试使用此代码:

#!/bin/bash

sum=0
ind=0

while IFS='' read -r line || [[ -n "$line" ]]; do
   if [[ $line =~ ^[a-zA-Z\ ]+$ ]]
   then
        ${sum}=${sum}+${#line} 
        ${ind}=${ind}+1 
        echo ${sum}
   fi        
done < "$1"

value=${sum}/${ind}
echo ${value}

此代码的打印始终为0/0,并且有些错误如:

./test1: line 9: 0=0+13: command not found
./test1: line 10: 0=0+1: command not found

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您的脚本部分问题已得到解答here ..您的变量分配不正确。您只能将$ 引用用于已分配的变量。分配过程会丢弃美元符号。

您遇到的另一个问题是您的算术不在arithmetic expression内表达。

请注意,您可以使用arithmetic expansion来处理变量:

  if [[ $line =~ ^[a-zA-Z\ ]+$ ]]; then
      (( sum += ${#line} ))
      (( ind++ ))
      printf '%s\n' "$sum"
  fi

以后......

value="$(( sum / ind ))"
printf '%s\n' "$value"

请注意bash只能处理整数数学,浮点数会被截断。要获得更高级的数学运算,请考虑使用bcdc(它们不是bash内置的,它们是可能需要在系统上安装的单独工具)或其他语言,例如awk或者perl可以做更好的表现和更精确的数学运算。

那说,你可以&#34;假&#34;如果你真的需要:

,可以使用一些额外的代码和字符串操作来处理几个小数位
$ sum=100; ind=7
$ printf -v x '%d' "$((${sum}00/${ind}))"
$ printf '%d.%d\n' "${x%??}" "${x:$((${#x}-2))}"
14.28

第一个printf具有除数,它将被除数乘以100(在它之后加上两个零)。然后用第二个printf分割得到的商以插入小数点。这是一个黑客。使用支持真实数学的工具。