ファイル列の平均を求める

ファイル列の平均を求める

タイムスタンプデータを含むCSVファイルと、毎月別々のファイルに分割するスクリプトがあります。このスクリプトはその月のデータを取得し、平均を単一の値として計算します。コードの一部は次のとおりです。他のすべての月は1月の最初の月と同じです。このコードは、1年の長さのファイルを9列に基づいて数ヶ月(1〜12月)に分割し、17フィールドすべてを印刷します。次のコード行は列13を表示し、ファイル内のすべてのデータ(欠落データを無視、-999と指定)の平均を計算し、列平均を新しい$ i.monthlyavgファイルに印刷します。

awk -F ',' '$9= 1 {print $0}' $i > Jan.tmp
awk 'NR > 1 { for i = 13) if ($i != -999) {sum[i] += $i; num[i]++}
END { for (i = 13) print i, sum[i], num[i], sum[i]/num[i] }' Jan.tmp > $i.monthlyavg

次のエラーメッセージが表示されます...

awk: cmd. line:1: NR > 1 { for i = 13) if (01-073-1003-SO2-1998.dat.out != -999) {sum[i] += 01-073-1003-SO2-1998.dat.out; num[i]++}
awk: cmd. line:1:              ^ syntax error
awk: cmd. line:1: NR > 1 { for i = 13) if (01-073-1003-SO2-1998.dat.out != -999) {sum[i] += 01-073-1003-SO2-1998.dat.out; num[i]++}
awk: cmd. line:1:                    ^ syntax error
awk: cmd. line:1: NR > 1 { for i = 13) if (01-073-1003-SO2-1998.dat.out != -999) {sum[i] += 01-073-1003-SO2-1998.dat.out; num[i]++}
awk: cmd. line:1:                                                  ^ syntax error
awk: cmd. line:1: NR > 1 { for i = 13) if (01-073-1003-SO2-1998.dat.out != -999) {sum[i] += 01-073-1003-SO2-1998.dat.out; num[i]++}
awk: cmd. line:1:                                                              ^ syntax error
awk: cmd. line:1: NR > 1 { for i = 13) if (01-073-1003-SO2-1998.dat.out != -999) {sum[i] += 01-073-1003-SO2-1998.dat.out; num[i]++}
awk: cmd. line:1:                                                                                                   ^ syntax error

そして

 END { for (i = 13) print i, sum[i], num[i], sum[i]/num[i] }
awk: cmd. line:2:       ^ syntax error
awk: cmd. line:2:       END { for (i = 13) print i, sum[i], num[i], sum[i]/num[i] }
awk: cmd. line:2:                        ^ syntax error
awk: cmd. line:2:       END { for (i = 13) print i, sum[i], num[i], sum[i]/num[i] }
awk: cmd. line:2:                                                                  ^ unexpected newline or end of string

問題は何ですか?

答え1

9列の個々の値ごとに13列の数値平均を取得したい場合は、9列の各値に対して別々のファイルを作成する必要はありません。個々の合計を追跡し、最後にすべてを出力します。

awk -F, '
    $13 != -999 { s[$9] += $13; n[$9]++ }
    END { for (i in s) print i, s[i]/n[i] }' some-file

コードの主な問題は、ループの作成方法に構文エラーがあることですforfor列 13 のみにアクセスするので、ループはまったく必要ありません。


ループforには2つのスタイルがありますawkforおそらく使用したい「算術ループ」があります。通常、カウンタを使用していくつかの初期化から始まり、いくつかのロジックがテストされなくなるまで繰り返されます。本物、いくつかのアップデート:

for (initialization; logical-test; update) statement

例えば

for (i = 1; i <= NF; ++i) print i

他の型は上記の回答で示した型で、配列のインデックスを繰り返すために使用されます。ループは特定の順序でインデックスを繰り返すことはできません。

for (index-variable in array) statement

例えば

for (key in data) print key, data[key]

答え2

for (i = 13)まったく有効な awk 構成ではありません。 (これがfor i = 13) 構文的にまったく有効ではないことを必ず言うべきですか?)forこのステートメントには2つのバージョンがあります。

  • for (expr1; expr2; expr3) statement
  • for (var in array) statement

最初の()を使用したいようです。 17フィールドをすべて表示するには、またはを使用できます。フィールド#13のみを処理してループ構造を維持したい場合は、次のものを使用できます。ただし、この特定のタスクを実行するための簡単で簡単なコードが必要な場合は、次のように使用できます。for (expr1expr2expr3statementfor (i = 1; i <= 17; i++)for (i = 1; i <= NF; i++)for (i = 13; i <= 13; i++)

  • i = 13; if ($i != -999) {sum[i] += $i; num[i]++}
  • if ($13 != -999) {sum[13] += $13; num[13]++}または
  • if ($13 != -999) {sum += $13; num++}

...一つの列だけを扱う場合には配列が必要ないからです。

そして「彼ら」が述べたように非常に非常に二重引用符で awk を実行するのと同じです。すべてが正常ですとてもたくさん一重引用符を使用する方が良いです。

関連情報