0

我无法使用 awk 计算特定文本标识符下方列中特定数字的平均值。我有两列数据,我试图在重复的公共标识符上开始平均键控,即 01/1991。因此,awk 应该计算从 01/1991 开始的所有行的平均值,然后重复使用接下来的 21 行,其中 1991-2012 年的总行数为平均值 = 22。所需的输出是 1991 年至 2012 年每年所有一月 (01) 的每个 TextID/Name 条目的平均值,如下所示:

TextID/Name 1 Avg: 50.34 TextID/Name 2 Avg: 45.67 TextID/Name 3 Avg: 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

非常感谢您对解决方案的解释!我已经用更多描述编辑了原始答案 - 再次感谢您。

4

2 回答 2

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--; }'

它有一个计数器 l ,它设置为要计数的行数,然后将这些行数相加。

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

于 2013-02-22T23:25:46.243 回答
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
于 2013-02-22T23:02:22.453 回答