我在使用awk计算特定文本标识符列中的特定数字的平均值时遇到问题。我有两列数据,我试图开始平均键入重复的公共标识符,即01/1991。因此,awk应该计算从01/1991开始重复的所有行的平均值,使用接下来的21行,总行数为平均值= 22,即1991 - 2012年的总年数。所需的输出是1991年至2012年每年1月(01)的每个TextID / Name条目的平均值:
TextID / Name 1 平均值:50.34 TextID /名称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 :(得分: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汇总到下一行,这可能更强大。
答案 1 :(得分: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