在 perl/awk 中使用 shell 脚本计算平方和

在 perl/awk 中使用 shell 脚本计算平方和

我有如下 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"

awkor有更简单的方法吗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

对于大浮点数据,您可以使用perlbignum

$ paste file1 file2 | perl -Mbignum -anle '
    $sum += ($F[0] - $F[1])**2;
    END {     
        print $sum/$.;
    }                
'
0.02286666666666666666666666666666666666667

相关内容