我有如下 2 个文件。
文件1
0.34
0.27
0.32
文件2
0.15
0.21
0.15
现在,我想计算每列之间的平方和。例如,
[(0.34 - 0.15)^2 + (0.27 - 0.21)^2 + (0.32 - 0.15)^2 ] / 3
在哪里3是文件中的总行数。我将在两个文件中拥有相同的行数。
我想出了下面的 bash 脚本,它工作得很好,但我想知道是否还有其他更简单的方法。
#! /bin/bash
sum=0.0
while true; do
read -r lineA <&3
read -r lineB <&4
if [ -z "$lineA" -o -z "$lineB" ]; then
break
fi
diff=$(bc <<< "scale=5; $lineA - $lineB")
square=$(bc <<< "scale=5; $diff*$diff")
sum=$(bc <<< "scale=5; $sum+$square")
done 3<file1 4<file2
filelen=`wc -l file1 | cut -f1 -d' '`
final=$(bc <<< "scale=5; $sum/$filelen")
echo "$final"
awk
or有更简单的方法吗perl
?
编辑
我的输入文件中有 200 万行,输入文件实际上包含如下所示的科学数字。
3.59564e-185
我的脚本以及建议的答案在科学数字上失败了。但是,当我将科学数字更改为符号时,我可以使问题中的脚本正常工作10^
。
我按如下方式转换了输入文件。
sed -e 's/[eE]+*/\*10\^/' file1 > file1_converted
sed -e 's/[eE]+*/\*10\^/' file2 > file2_converted
现在,建议的 2 个答案失败了,给我的错误消息为Nan
。我的脚本似乎可以工作,但对于 200 万行,执行需要很长时间。
有什么有效的方法让它发挥作用吗?
答案1
一种方法是使用它,paste
因为您的文件具有相同的行数。
paste file1 file2 | awk '{s += ($1-$2)^2}; END{print (s+0)/NR}'
0.0228667
答案2
awk 'FNR==NR { file1[NR]=$1; next; }; { diff=$1-file1[FNR]; sum+=diff^2;};
END { print sum/FNR; }' file1 file2
答案3
对于大浮点数据,您可以使用perl
它bignum
:
$ paste file1 file2 | perl -Mbignum -anle '
$sum += ($F[0] - $F[1])**2;
END {
print $sum/$.;
}
'
0.02286666666666666666666666666666666666667