AWK输出问题

时间:2018-04-02 13:18:25

标签: awk

我编写了一个脚本,用于从数据文件中获取MEAN和STDEV。 假设数据文件包含以下数据:

1 
2 
3 
4 
5

awk脚本看起来像这样

awk '{MEAN+=$1/5}END{print MEAN, STDEV=sqrt(($1-MEAN)**2/4)}' dat.dat>stat1.dat

但它给了我一个不正确的STDEV值= 1。它必须是1.5811。你知道我的剧本中有什么不对吗?我怎么能改进它?

4 个答案:

答案 0 :(得分:1)

请问您可以尝试关注并告诉我这是否对您有所帮助(这应该适用于提供的数据,如果您的实际文件也有更多字段)。

awk '{for(i=1;i<=NF;i++){sum+=$i};mean=sum?sum/NF:0;sum="";for(j=1;j<=NF;j++){$j=($j-mean)*($j-mean);sum+=$j};print "Mean=",mean", S.D=",sqrt(sum/NF)}'  Input_file

现在也添加非单线形式的解决方案。

awk '
{
  for(i=1;i<=NF;i++){  sum+=$i  };
  mean=sum?sum/NF:0;
  sum="";
  for(j=1;j<=NF;j++){  $j=($j-mean)*($j-mean);
                       sum+=$j};
                       print "Mean=",mean", S.D=",sqrt(sum/NF)
}
'  Input_file

编辑: 添加类似于上面的代码只添加异常处理的类型,如果任何值为ZERO那么它应该打印0。

awk '
{
  for(i=1;i<=NF;i++){  sum+=$i  };
  mean=sum?sum/NF:0
  sum="";
  for(j=1;j<=NF;j++){  $j=($j-mean)*($j-mean);
                       sum+=$j};
                       val=sum?sqrt(sum/NF):0
                       print "Mean=",mean", S.D=",val
}
'  Input_file

答案 1 :(得分:1)

即使标题和标签说awk,我想补充一点,使用datamash可以轻松完成计算一列数据的均值和stdev:

seq 1 5 | datamash mean 1 sstdev 1
3   1.5811388300842

这可能是偏离主题的(并且我意识到在awk编写简单的任务可能是一个很好的学习机会),但我认为datamash值得注意,特别是对于简单的计算比如这个。该文档提供了它可以执行的所有功能,以及包含许多列的文件的良好示例。这是一种快速可靠的替代方案。希望它有所帮助!

答案 2 :(得分:1)

你可以一次性做同样的事情

$ seq 5 | awk '{sum+=$1; sqsum+=$1^2} 
            END{mean=sum/NR; 
                print mean, sqrt((sqsum-NR*mean^2)/(NR-1))}'

3 1.58114

请注意,这是&#34;样本人口的标准定义&#34; (除以N-1)。

答案 3 :(得分:0)

这是一个两遍可流式版本:

parse.awk

# First-pass:  sum the numbers
FNR == NR { sum += $1; next }

# After first pass:  determine sample size (N) and mean
# Note:  run only once because of the f flag
!f { 
  N    = NR-1    # Number of samples
  mean = sum/N   # The mean of the samples
  f    = 1
}

# Second-pass:  add the squares of the sample distance to mean
{ varsum += ($1 - mean)**2 }

END {
  # Sample standard deviation
  sstd = sqrt( varsum/(N-1) )
  print "Sample std: " sstd
}

像这样运行文件:

awk -f parse.awk file.dat{,}

对于溪流运行它:

awk -f parse.awk <(seq 5) <(seq 5)

两种情况下的输出:

Sample std: 1.58114