2013-02-22 147 views
0

我在使用awk计算特定的文本标识符列中的特定数字的平均值时遇到了麻烦。我有两列数据,我试图开始平均键入一个重复的公共标识符,即01/1991。因此,awk应该计算从1991年1月1日开始的所有行的平均值,重复使用下一行21行,总行数为平均值= 22,总计1991 - 2012年。所需的输出,平均每个文本ID /名称条目的所有月份的(01)为每年1991年至2012年显示如下:Awk Calc平均行低于某些行

文本ID /名称1 均价:50.34 文本ID /名称2 均价:45.67 TEXTID /名称3 平均:39.97 ...

样本数据:

TextID/Name 1 
01/1991, 57.67 
01/1992, 56.43 
01/1993, 49.41 
.. 
01/2012, 39.88 
TextID/Name 2 
01/1991, 45.66 
01/1992, 34.77 
01/1993, 56.21 
.. 
01/2012, 42.11 
TextID/Name 3 
01/1991, 32.22 
01/1992, 23.71 
01/1993, 29.55 
.. 
01/2012, 35.10 
continues with the same data for TextID/Name 4 

我得到使用此代码的答案如下所示,但平均开始以计算特定标识符行之前和不在该线以下(01/1991)。

awk '$1="01/1991" {sum+=$2} (NR%22==0){avg=sum/22;print"Average: "avg;sum=0;next}' myfile 

感谢和解释的解决方案,非常感谢!我用更多描述编辑了原始答案 - 再次感谢你。

+0

我觉得你想'awk'$ 1 ==“....'。'$ 1 =”xxx“'分配给字段1。祝你好运。 – shellter 2013-02-22 21:55:24

+0

感谢您的回复,但是当我计算所有零时的平均值 – user2100039 2013-02-22 21:59:27

+0

关于'$ 1 =“01/1991”的另一件事是,因为它是一个赋值,它将始终为真,并且所有记录都将处理'sum + = $ 2'。如果你充实了你的现在我们不知道为什么你选择了22(我可以猜到),更重要的是,我们不知道你想要的输出,也没有你现有输出的真实图像,或者你可以添加一些打印语句所有的变量都可以自己调试问题,祝你好运。 – shellter 2013-02-22 22:49:25

回答

0

如果你被允许使用Perl,而不是awk中,你可以这样做:

#!/usr/bin/env perl 

$start = 0; 
$have_started = 0; 
$count = 0; 
$sum = 0; 

while (<>) { 
    $line = $_; 

    # Grab the value after the date and comma 
    if ($line = /\d+\/\d+,\s+([\d\.]+)/) { 
    $val = $+; 
    } 

    # Start summing values after 01/1991 
    if (/01\/1991,\s+([\d\.]+)/) { 
    $have_started = 1; 
    $val = $+; 
    } 

    # If we have started counting, 
    if ($have_started) { 
    $count++; 
    $sum += $+; 
    } 
} 

print "Average of all values = " . $sum/$count; 

运行它,就像这样:

$ cat your-text-file.txt | above-perl-script.pl 
1

如果你看一下你的文件,第一场是“01/1991”,最后用逗号,而不是“01/1991”。此外,NR%22 == 0将查看可以被22整除的行号,而不是22行后它认为你关心的点。

你可以做这样的事情,而不是:

awk ' 
    BEGIN { l=-1; } 
    $1 == "01/1991," { 
    l=22; 
    s=0; 
    } 

    l > 0 { s+=$2; l--; } 
    l == 0 { print s/22; l--; }' 

它有它设置为行数数的计数器1,那么其总结了该行数。

您可能想要考虑简单地总结从01/1991到下一个的所有行,这可能更加健壮。