2

我想用输入文件中的一堆数字加载一个临时文件。脚本的格式是“testing -row/-col [input file]”。输入文件大多只是一堆随机数,比如

1 2 3 4
3 3 5 6
9 4 4 2

我下面的代码试图抓住这个输入文件作为参数,然后将这些数字“cat”到一个新的临时文件中。从那里,我试图从这个临时文件中找到行的平均值。

FILENAME=$2
TMP=./TMP2.$$
cat $FILENAME > $TMP

#average row 
function avg_row {
while read -a row  
do
    total=0
    sum=0
    for i in "${rows[@]}"
    do
         eum=`expr $sum + $i`
         total=`expr $total + 1`
    done
    average=`expr $sum / $total`
    echo $average
done < $TMP
}

然而,即使当我“cat” TMP 文件时,它显示的内容与 testing_file 完全相同,但当我运行它打印的脚本时

 expr: division by zero
 expr: division by zero
 expr: division by zero

关于为什么会发生这种情况的任何建议或想法?谢谢你。

4

1 回答 1

1

两个问题:

  1. 您的函数读取数组row,但随后尝试访问不存在的数组rows。因为rows没有条目,total所以永远不会增加并且除法是被零除。

  2. 此行更新eum,而不是sum

    eum=`expr $sum + $i`
    

此外,还不清楚为什么 $FILENAME 的内容在被读取之前会被复制。我会假设你有充分的理由这样做。

修正后的函数如下所示:

function avg_row {
while read -a row  
do
    total=0
    sum=0
    for i in "${row[@]}"
    do
         sum=`expr $sum + $i`
         total=`expr $total + 1`
    done
    average=`expr $sum / $total`
    echo $average
done < $TMP

这将产生输出:

$ avg_row
2
4
4

现代化的 bash 版本

反引号和expr过时的。该函数的更现代的 bash 版本是:

avg_row2() {
while read -a row
do
    sum=0
    for i in "${row[@]}"
    do
        ((sum += i))
    done
    echo $((sum / ${#row[@]}))
done < $TMP
}

这会产生与以前相同的输出:

$ avg_row2
2
4
4

awk 版本

同样的事情可以在 awk 中完成:

$ awk '{s=0; for (i=1;i<=NF;i++) s+=$i; print int(s/NF);}' filename
2
4
4

与 bash 不同,awk 可以进行浮点运算:

$ awk '{s=0; for (i=1;i<=NF;i++) s+=$i; print s/NF;}' filename
2.5
4.25
4.75
于 2015-10-07T05:36:31.120 回答