读取、存储和访问临时文件 (BASH)

Read, Store and Access Temporary Files (BASH)

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

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

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

FILENAME=
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

关于为什么会发生这种情况有什么建议或想法吗?谢谢。

两个问题:

  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