0

awkを使用して、特定のテキスト識別子の下の列にある特定の数値の平均を計算するのに問題があります。2 つの列のデータがあり、1991 年 1 月に繰り返される共通の識別子で平均的なキーイングを開始しようとしています。したがって、awk は 1991 年 1 月から始まるすべての行の平均を計算する必要があります。これは、次の 21 行を使用して、1991 年から 2012 年までの合計行数の平均 = 22 行を使用して繰り返されます。目的の出力は、1991 年から 2012 年までのすべての 1 月 (01) の各 TextID/Name エントリの平均です。以下に示します。

TextID/名前 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

解決策の感謝と説明は大歓迎です! 元の回答を編集して説明を追加しました-ありがとうございます。

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 があり、その行数を合計します。

ただし、1991 年 1 月から次の行までのすべての行を単純に合計することを検討することをお勧めします。

于 2013-02-22T23:25:46.243 に答える
0

Awk の代わりに Perl を使用することが許可されている場合は、次のようにすることができます。

#!/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 に答える