使用bash获取一行中所有数字和文件中所有行的平均值



本质上,我有一个包含几千行的txt文件,每行包含300个数字。我需要取每行300个数字的平均值,然后取文件中所有平均值的平均值a la;

0.4,0.5,0.6,0.7...
0.5,0.6,0.7,0.8...
0.6,0.7,0.8,0.9...
to
0.55
0.65
0.75
to
0.65

我试过一些在网上找到的bash脚本,但它们都是关于列的平均值,而不是整个行的平均值。我目前的策略是用两个脚本来做这个操作,一个是找到每行的平均值,另一个是一起找到所有行的平均数,但我什么都想不出来。我对bash和UNIX命令还很陌生,所以解决方案可能很明显,但我还没有找到

Bash是高级任务的外壳,对于典型的编程、读取文件和执行算术来说不是最佳选择。awk是执行此任务的标准bash工具。这是一个脚本:

> cat tst.awk
BEGIN { FS = "," }
{
sum = 0
for (i=1;i<=NF;i++) sum += $i
avg = sum / NF
total += avg
print "Line " NR ": " avg
}
END { print "Lines average: " total/NR }

使用和输出:

> awk -f tst.awk file
Line 1: 0.55
Line 2: 0.65
Line 3: 0.75
Lines average: 0.65

FS是要使用的字段分隔符。在读取第一行之前执行BEGIN {}部分。awk逐行读取文件,并且对于每个输入行执行主体CCD_ 3。里面的代码不言自明,与标准编程语言非常相似。在到达文件末尾之后,执行END {}

这就是你可以做的,只需简单的算术和for循环:

#!/bin/bash
data=$(cat data.txt) # Your primary data
all=0
l=0
for i in $data; do
line=0
k=0
oldIFS=$IFS
IFS=','
for j in $i; do
line=$(echo "scale=2; ($line+$j)" | bc)
((k++))
done
IFS=$oldIFS
line=$(echo "scale=2; $line/$k" | bc)
echo "Line $l: $line"
all=$(echo "scale=2; ($all+$line)" | bc)
((l++))
done
all=$(echo "scale=2; $all/$l" | bc)
echo "Final result: $all"

结果:

Line 0: .55
Line 1: .65
Line 2: .75
Final result: .65

注意此处的IFS变量,用于更改for循环中的分隔符:https://bash.cyberciti.biz/guide/$IFS

最新更新