AWK で十分ですよ - その1 - 和,平均,最大,最小

2011年 8月 1日 掲載


「AWK なんて化石だ」

Perl を使っていたころはそう思っていた. が,データを解析する分には,AWK で十分どころか, Perl なんかを使うよりずっと楽だということがわかり, 今では毎日 AWK のお世話になっている. そんな AWK でいかに処理が簡単に書けるかを,この連載では紹介していこうと思う.

このような趣旨で書いていくので,掲載するスクリプトは簡単なものばかりになる. あらかじめご承知おき願いたい.


今回は,超基本的な統計量を求めるスクリプトを紹介する.

まずは,サンプルデータの用意である. もちろん AWK で作る.

$ awk 'BEGIN{for(i = 0; i < 100; i++) print rand()}' > data.txt

これで,100個の乱数列が書き込まれたファイル data.txt ができたはずである.

$ wc -l data.txt
     100 data.txt
$ head data.txt
7.82637e-06
0.131538
0.755605
0.45865
0.532767
0.218959
0.0470446
0.678865
0.679296
0.934693

今回は,このデータを解析していく.


まずは,データの個数をチェックするスクリプト count.awk.

END{
  print NR
}

これだけである.実際に使ってみよう.

$ awk -f count.awk data.txt
100

ちゃんとデータの個数が数えられている.

次は,データの合計を出力するスクリプト sum.awk である.

{
  sum += $1
}
END{
  print sum
}

data.txt の合計は,

$ awk -f sum.awk data.txt
51.8425

となる.

データ数と和がわかれば,平均値を計算できる. 平均値を計算するスクリプト average.awk は,

{
  sum += $1
}
END{
  print sum / NR
}

と書けば,だいたいの場合は OK だが, 空のデータファイルを読み込んだとき 0除算エラーになるので,

{
  sum += $1
}
END{
  if(NR == 0) exit

  print sum / NR
}

と書いておく. 実行例は以下のとおり.

$ awk -f average.awk data.txt
0.518425
$ awk 'BEGIN{}' > empty.txt
$ awk -f count.awk empty.txt
0
$ awk -f average.awk empty.txt
$

空のファイル empty.txt を読ませても平気である.

sum.awk も,データが空のときは何もしないように書きなおしておこう.

{
  sum += $1
}
END{
  if(NR == 0) exit

  print sum
}

データの最大値,最小値を求めるスクリプトも書いてみる.

最大値を求める max.awk は,

NR == 1{
  max = $1
}
{
  if($1 > max) max = $1
}
END{
  if(NR == 0) exit

  print max
}

最小値を求める min.awk は,

NR == 1{
  min = $1
}
{
  if($1 < min) min = $1
}
END{
  if(NR == 0) exit

  print min
}

となる.

以下に,実行例を示す.

$ awk -f max.awk data.txt
0.999458
$ awk -f min.awk data.txt
7.82637e-06

AWKスクリプトは,1行目に「#!/usr/bin/awk -f」と書いて, 実行可にし,パスを通しておけば,コマンドのように使えて便利である. 1行目に「#!/usr/bin/awk -f」を追加するのも AWK で簡単にできる.

$ awk 'NR == 1 && !/^#!/{print "#!/usr/bin/awk -f"}{print $0}' count.awk
#!/usr/bin/awk -f
END{
  print NR
}

すでに「#!〜」がある場合は追加しないように書いておいた. こうしておけば,追加済みのスクリプトと未追加のスクリプトが混在していても,まとめて処理ができる.


今回の AWKスクリプト:


次回につづく.


[ KDO ホームにもどる ]


(C) 2011 KDO