Awkでcsvを一括処理

研究室向けシリーズその1。
研究室用のマニュアルの下書きです。

awk is 何

awkはファイルを行単位で処理することに特化した言語です。ファイル処理に特化したCくらいの認識でひとまずOK

インストール

windows版のawkgawkと呼ばれてます。

1. Gawk for WindowsからComplete package, except sourcesと書いてある物をダウンロード

2. C:\Program Files (x86)\GnuWin32\binにpathを通す。

3. コマンドプロンプトgawkと打って何か色々出てきたら完了です。

脇道:path通すって?

 コマンドプロンプトでexeなどを指定するとき、もちろんwindows特定できるようにしてあげないと実行することができません。windowsは何か実行ファイル等が指定された時、コマンドプロンプト上で自分が現在いるディレクトリとpathが通ってるディレクトリを探します。なのでpathを通しておけばコマンドプロンプト上で特にどこにあるか言わなくても勝手に実行ファイルを探してくれます。*1
 ちなみにnotepad.exe*2とかはC:\Windowsに入っているけど、このフォルダもちゃんとpathが通ってたりするので、コマンドプロンプト上でnotepad*3と打つとメモ帳が出る。
 利用方法から説明してしまったがpathというのは環境変数PATHのこと。結局、コマンドプロンプトが動作するときに環境変数PATHに書いてあるフォルダからプログラムを探していきますよーくらいの意味

awk 文法

 実際に書く前にいくつか決まり事を
FS: field separatorのこと、 csvなら","が区切り文字 tab区切りやスペース区切りの場合もある。
NR: number of rowのこと、awkが今処理している行番号
$0: その行全体が入っている変数
$1,$2,...: それぞれ(FSによって区切られた)1列目、2列目、...が入っている変数
BEGIN{~~}:awk開始時に一度だけ実行される
END{~~}:awk終了時に一度だけ実行される
{~~}:各行に対する処理
(パターン){~~}:パターン(NR>2とか$1 == 1とか)に当てはまった各行に対する処理

awkの文法はだいたいこれでマスターできたはずです。おめでとう(・ω・)

awk 入門

 文法説明してから入門かよ感が半端ないですが、とりあえず
お好きなcsvとして

a,b,c
1,2,3
4,5,6
7,8,9

みたいなtest.csvがあるとします。

試しにいくつか実行してみます。

<各行で行の全体を表示>
gawk -F "," "{print $0}" test.csv
a,b,c
1,2,3
4,5,6
7,8,9

<各行で行の一列目を表示>
gawk  -F "," "{print $1}" test.csv
a
1
4
7

<一行目以降の行(NR>1の行)で行の二列目を表示>
gawk  -F "," "NR>1 {print $2}" test.csv
2
5
8

<3列目が5より大きい行で行の一列目を表示>
gawk  -F "," "$3>5 {print $1}" test.csv
a
4
7

だいたい、こんな雰囲気で記述していきます。
(条件){命令}の形式で条件にマッチした時に命令が実行されるようになっています。
ちなみに-F ","でフィールドセパレータを指定しています。

awkのプログラムを"$3>5 {print $1}"のようにコマンドプロンプト上に全部書いていくと複雑になるにつれて恐ろしく見難くなりそうなので、ファイルに書いていきます。
指定方法は-f (ファイル名)です。
特に理由はないですが気分で2行目から1列目と2列目を表示しながら1列目の和を最後に表示する処理を書きました。

sum.awk

BEGIN {
  FS = ","
  a = 0
}

NR > 1{
  print $1+$2
  a = a+$1
}

END {
  print a
}
gawk -f sum.awk test.csv
3
9
15
12

awkファイル中でファイルセパレータを指定してみました。変数も宣言なしでがしがし使えます。batのforと組み合わせて100個単位のcsvをがりがり処理すると楽しいです。パターンも正規表現が使えます。ifとかforとかfunctionとかも使えるので調べてみてください。

おまけ

gawk "{print $0}" 1.csv 2.csv 3.csv
gawk "{print $0}" *.csv

のようにすると複数ファイルに対して処理が行えます。(下はファイル名末尾が.csvになっている全てのファイルに対して処理を行う。)処理としては1.csv, 2.csv, 3.csvを順に結合したファイルを一回だけ処理しています。END{print $0}で各ファイルの最終行だけ表示とかやりたい場合は別の方法でやらないとだめです。

*1:逆に言うと、pathを通さなくてもgawk起動時にC:\Program Files (x86)\GnuWin32\bin\gawkと毎回書けば問題なく使える。ちょっと面倒だけど・・・

*2:メモ帳

*3:exeファイルを指定するときはexeを省略することができる。