读取、存储和访问临时文件 (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
关于为什么会发生这种情况有什么建议或想法吗?谢谢。
两个问题:
您的函数读取数组 row
,但随后尝试访问不存在的数组 rows
。因为 rows
没有条目,所以 total
永远不会递增并且除法是被零除。
这一行更新 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
我想用输入文件中的一堆数字加载一个临时文件。 脚本的格式是"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
关于为什么会发生这种情况有什么建议或想法吗?谢谢。
两个问题:
您的函数读取数组
row
,但随后尝试访问不存在的数组rows
。因为rows
没有条目,所以total
永远不会递增并且除法是被零除。这一行更新
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