Perl/awk에서 쉘 스크립트를 사용하여 제곱합 계산

Perl/awk에서 쉘 스크립트를 사용하여 제곱합 계산

아래와 같이 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

어디파일의 총 줄 수입니다. 두 파일 모두 동일한 수의 줄을 갖게 됩니다.

나는 다음 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아니면 더 쉬운 방법이 있나요 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

관련 정보