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

时间:2015-10-07 05:26:13

标签: bash expr

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

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
}

然而,即使我和猫一起#34;它显示的TMP文件与testing_file完全相同,当我运行脚本时,它打印

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

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

1 个答案:

答案 0 :(得分:1)

两个问题:

  1. 您的函数读入数组row,但随后尝试访问不存在的数组rows。由于rows没有条目,total永远不会递增,并且除法是除零。

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

    eum=`expr $sum + $i`
    
  3. 此外,还不清楚为什么$ 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