Walk, Don't Run

若手エンジニアが日々学んだことをさらけ出すブログです

Windowsユーザーでもawkを使いたい

最近会社でDB-Unitを使ってガッツリとテストをするのが流行っている(自分の中で)。DB-Unitを使う場合、データベースに入れる前提データや、assertする正解データをcsvの形式で扱うことができる。しかし、テーブルに列追加・列削除が入った場合に、これらのcsvファイルも更新する必要がある。

csvは結局ただのテキストデータなので、こういったファイルを編集するのにはやはりawkが便利だ。しかし、悲しいことに会社のPCはWindowsなので、気軽にawkを使えない。色々と探した結果、JavaのVM上でawkを実行できる"Jawk"が便利そうだ。

Jawkに決めた理由は、awk本体をインストールする必要がないためだ。Windows版のawkをインストールするのはもちろん構わないのだが、自分以外のメンバーに使ってもらうと思った時に、わざわざインストールしてもらう手間を考えると、Jawkがあればいっか、と思ったのだ。

Jawkの使い方

この辺りを参考にさせて頂きました。すごく簡単。jawkのjarをダウンロードして、以下のようにターミナルから実行する。

java -cp jawk.1_02.jar org.jawk.Awk -f awkProgram.awk test.csv

awkProgram.awkってのは適当なawkファイル。スクリプトファイルからawkを実行するのではなく、コマンド直打ちでももちろん使える。

awkCSVファイルの特定列を削除

awkで出来ることをJavaで書こうとすると、ソースの分量が一気に増えてしまって、正直やってられない。やりたかったことはcsvファイルの列追加や列削除であり、awkだとこんな感じにシンプルに書ける。

BEGIN {
  FS   = ","
  sepa = ","
}

{
  cnt = 0;

  for (i = 1; i <= NF; i++) {
    #引数で指定した番号は出力しない
    if (i == para) {
      continue
    }
    #一番最初の列はセパレータを付けない
    if (cnt == 0) {
      printf($i)
    } else {
      printf(sepa $i)
    }
    #カウントのインクリ
    cnt++
  }

  printf("\n");
}

実行するときは、-vオプションで引数を指定する。

java -cp jawk.1_02.jar org.jawk.Awk -v para=3 -f awkProgram.awk test.csv

paraという引数(任意に変数名は指定できる)に、例えば3を指定すると、test.csvの三列目がガッツリ削除される。おそらくもっとシンプルに、それこそ1〜3行程度で書けるはずだが、割と丁寧目に書くとこんな感じになった。

awkは時代遅れ?

awkは研究室時代にちょっと触れた程度だったので、正月に暇つぶしがてらにドットインストールでawkの復習をしたのだが、こんなに使いやすかったのか!と非常に興奮した。相当古い言語(というかただのLinuxコマンド?)だが、思ったよりずっと洗練されていて、比較的新しい言語と同様の実装がなされていた。連想配列が使えるなんて知らなかった。

用途が限定されてはいるが、Windowsユーザーでも学ぶ価値は十分にあるので、是非色んな人に触ってほしい。あと、ドットインストールはすごくわかりやすくていつもお世話になってます。