AWK とは、構造化されたテキストを対象とした、文字列処理ソフトである。
UNIX では awk または gawk として使える。 Windows では https://osdn.jp/projects/sfnet_ezwinports/releases/ などを見れば最新バージョンが手に入る。 2016/04/30 現在では 4.1.3 が最新である。ちなみに、Windows 64 bit 対応はない。
zip ファイルをダウンロードして展開すると、bin と lib, share の 3 フォルダが表示される。 どのようにしてもいいだろうが、これら3フォルダが入っている親フォルダを C:\awk として使っている。
として実行すると次のように表示される。
GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.0-p8, GNU MP 5.0.2)
Copyright (C) 1989, 1991-2015 Free Software Foundation.
PS C:> c:\awk\bin\gawk '{print $1}' .\foo.txt
gawk: cmd. line:1: (FILENAME=.\foo.txt FNR=1) fatal: print to "standard
output" failed (No space left on device)
この原因はよくわからない。読み込むテキストファイル foo.txt が 2 バイト文字で始まっていると上記エラーが出る。 行の先頭に ASCII 文字を最初に入れたら正常に表示された。
2 バイト文字だけで上記のエラーが出ないようにするには、DOS 窓を使って出力結果に nkf32 のフィルターを通せばよい。 なお、DOS 窓の代わりに PowerShell のウィンドウを使うと ??? ばかりが出て文字がばけてしまい、さえない。
次のようなデータがある。仮に earthquake.txt に入っているものとする。
404 ,1995-01-17 ,34.6, 135.0, 7.3, 1, 兵庫県南部地震, 2, Kobe earthquake, 3, 阪神・淡路大震災 411 ,2001-03-24 ,34.1, 132.7, 6.7, 1, 芸予地震 414 ,2003-09-26 ,41.8, 144.1, 8.0, 1, 十勝沖地震 415 ,2004-10-23 ,37.3, 138.9, 6.8, 1, 新潟県中越地震 418 ,2007-03-25 ,37.2, 136.7, 6.9, 1, 能登半島地震 419 ,2007-07-16 ,37.6, 138.6, 6.8, 1, 新潟県中越沖地震 420 ,2008-06-14 ,39.0, 140.9, 7.2, 1, 岩手・宮城内陸地震 423 ,2011-03-11 ,38.1, 142.9, 9.0, 1, 東北地方太平洋沖地震, 2, Tohoku earthquake, 3, 東日本大震災
上記の表は大地震をまとめた理科年表からとっている。 第1フィールドは理科年表の通し番号、第2フィールドは地震が起こった日付、第3、第4フィールドはそれぞれ震源の緯度(北緯)、経度(東経)、 第5フィールドはマグニチュードである。 一方、第6フィールド以下はその地震の一般的な呼び方で、レコード内裁判数字+読み方という繰り返しである。
上記の表を次のように加工したい。
404 ,1995-01-17 ,34.6, 135.0, 7.3, 1, 兵庫県南部地震, 404 ,1995-01-17 ,34.6, 135.0, 7.3, 2, Kobe earthquake, 404 ,1995-01-17 ,34.6, 135.0, 7.3, 3, 阪神・淡路大震災, 411 ,2001-03-24 ,34.1, 132.7, 6.7, 1, 芸予地震, 414 ,2003-09-26 ,41.8, 144.1, 8.0, 1, 十勝沖地震, 415 ,2004-10-23 ,37.3, 138.9, 6.8, 1, 新潟県中越地震, 418 ,2007-03-25 ,37.2, 136.7, 6.9, 1, 能登半島地震, 419 ,2007-07-16 ,37.6, 138.6, 6.8, 1, 新潟県中越沖地震, 420 ,2008-06-14 ,39.0, 140.9, 7.2, 1, 岩手・宮城内陸地震, 423 ,2011-03-11 ,38.1, 142.9, 9.0, 1, 東北地方太平洋沖地震, 423 ,2011-03-11 ,38.1, 142.9, 9.0, 2, Tohoku earthquake, 423 ,2011-03-11 ,38.1, 142.9, 9.0, 3, 東日本大震災,
つまり、1レコードで繰り返されているフィールドを複数レコードにしたいということである。 これは、次のような awk スクリプトを書けばできる。
# 1st.awk BEGIN{FS="," ; iter = 2; begin_iter = 5} { for (i = begin_iter + 1; i <= NF ; i += iter) { for (k = 1; k <= begin_iter; k++) { printf("%s,", $(k)) } for (j = 0; j < iter; j++) { printf("%s,", $(i + j)) } print "" } }
実行は次の通り。
awk -f 1st.awk earthquake.txt
LINUX では 関数 match を使う。