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