2016-03-21 51 views
0

我有一个文件名为test.txt下列要求:使用awk来计算数字的平均值

10 
200 
3000 
======= 
4 
5 
======= 

我需要写一个awk脚本来参加这个文件作为输入文本到awk脚本输出:

10 
200 
3000 

Average 1070.00 

4 
5 

Average 4.50 

我写我的剧本是这样的:

{while($1!~"=======") s+=$1;} 
{print "Average ", s} 

每次我跑第是代码,我用:

awk -f awrp4 test.txt 

但它崩溃了。我不知道我做错了什么。我是一个初学者,并试图了解awk函数,所以我很抱歉,如果这看起来很简单。欢迎任何帮助。

+1

你的意思是它打印的平均“崩溃“? awk中很少需要while循环,因为它设计为逐行扫描文件。你也没有做任何分工来找到你的平均水平。 – miken32

+0

它崩溃,因为'while($ 1!〜“=======”)s + = $ 1;'是一个无限循环。 –

回答

2

使用GNU awk的,你可以写:

gawk ' 
    BEGIN {FS = "\n"; RS = "\n=+\n"} 
    NF > 0 { 
     sum = 0 
     for (i=1; i<=NF; i++) { 
      print $i 
      sum += $i 
     } 
     printf "Average %.2f\n", sum/NF 
    } 
' file 
+0

观察:虽然数据是一次两行或三行的数据,但一次收集所有行并没有任何问题。如果数据一次有数百万行,那么这需要比逐行方式更多的内存。然而,你还必须开始担心溢出是否是一个问题(可能不是;'awk'将从整数变为'double')等等。现在,很少有台式机或服务器机器会受到严重的阻碍,即使是数据块中的几个字节也是如此,所以它主要是一种理论上的而非实际的反对意见。 –

1

当然无可厚非格伦的解决方案,但它可能是一个有点为您先进。这也许是更适合:

{ 
if ($1 == "=======") { 
    print "\nAverage " s/i "\n"; 
    s=0; 
    i=0; 
} else { 
    print $1; 
    s += $1; 
    i += 1; 
} 
} 

正如我在评论中提到的,awk的本质是通过文本文件的每一行循环。除非你正在做一些后处理或者处理数组,否则while循环可能没有多大用处。

+0

确保您在增加'i'前检查$ 1是否存在 –

+0

样本数据不包含任何空白行,因此我不想包含任何不必要的复杂情况。 – miken32

0
awk '$1~/^[[:digit:]]/ {i++; sum+=$1; print $1} $1!~/[[:digit:]]/ {print "Average", sum/i; sum=0;i=0}' file 
  • 第一部分检查是否从第1列的第一个字符是一个数字,如果是的话则递增计数器“i”和添加该记录(数)求和。
  • 第二部分是跳过不以数字开头的任何记录,然后除以和/我,终于复位计数器和总和为0