如何计算shell脚本中的标准差?

时间:2016-02-25 13:01:50

标签: bash shell unix standard-deviation

我有一个shell脚本:

dir=$1 
cd $dir 
grep -P -o '(?<=<rating>).*' * | 
awk -F: '{A[$1]+=$2;L[$1]++;next}END
{for(i in A){print i, A[i]/L[i]}}' | sort -nr -k2 | 
awk '{ sub(/.dat/, " "); print }'

总结了我文件夹的每个文件中<rating>字段后面的所有数字,但现在我需要计算数字的标准偏差而不是得到平均值。通过将文件中每个评级的差异与均方差相加,然后将其除以样本大小-1。我不需要在文件夹中的每个文件中执行此操作,而是在2个特定文件hotel_188937.dathotel_203921.dat中执行此操作。以下是其中一个文件的内容示例:

<Overall Rating>
<Avg. Price>$155
<URL>

<Author>Jeter5
<Content>I hope we're not disappointed! We enjoyed New Orleans...
<Date>Dec 19, 2008
<No. Reader>-1
<No. Helpful>-1
<rating>4
<Value>-1
<Rooms>3
<Location>5
<Cleanliness>3
<Check in / front desk>5
<Service>5
<Business service>5

<Author>...
repeat fields again...

第一个文件的样本大小为127,平均值为4.78,而样本大小为324,第二个文件的平均值为4.78。无论如何,我可以改变我的脚本来计算这两个特定文件的标准偏差,而不是计算我目录中每个文件的平均值?谢谢你的时间。

2 个答案:

答案 0 :(得分:2)

您可以在一个awk脚本中执行所有操作

$ awk -F'>' '
    $1=="<rating" {k=FILENAME;sub(/.dat/,"",k);
                   s[k]+=$2;ss[k]+=$2^2;c[k]++}
               END{for(i in s) 
                   print i,m=s[i]/c[i],sqrt(ss[i]/c[i]-m^2)}' r1.dat r2.dat

r1 2.5 1.11803
r2 3 1.41421

s表示求和,s表示平方和,c表示计数,m表示平均值。请注意,这会计算人口标准差而不是样本标准差。对于后者,您需要使用(count-1)进行一些缩放调整。

答案 1 :(得分:1)

*行中的grep告诉它搜索所有文件。

更改行

grep -P -o '(?<=<rating>).*' * | 

grep -P -o '(?<=<rating>).*' hotel_188937.dat hotel_203921.dat |