プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

AWK超簡単再入門

「この合成ログファイルから使用セルの数とサイズ求めるプログラム作れ」
「んー、各行にインスタンスパスとセル名とサイズとかがあるんすか。こんなん、プログラムじゃなくって、awkでいいじゃん」
「何でも良いから」
「あいよ」

 と、おもむろに端末を立ち上げて、awkと打ち込み数秒後

やっべ AWK忘れた


 たぶん、2年ぶりぐらいにawkの文字を打ち込んだんじゃないかな。クソニートだし、もうそろそろ痴呆が始まったかな。時間の流れは残酷だね

AWKとは

 一行一行を抜き出して、更にその行をセパレータ(デフォルトは空白)で分割して処理すると言うことを簡単に記述する処理系。
 CSVとか、何かの文字で区切られているテキストファイルを処理するのに向いている。

 処理系は幾つかあって、この記事ではgawk基準。

 大規模なプログラムも作れるらしいが、この記事はワンライナーで使うのに十分な程度しか解説しません。

自動定義される変数

 一行一行読み出した値や、分割されたデータは$0、$1といった変数に格納されます。

f:id:nodamushi:20180826151828p:plain

 

printとprintf

 出力する時はprintかprintf。print文は","(カンマ)区切りで変数を並べるか、" "(半角スペース)区切りで変数を並べる。カンマ区切りの場合は、出力結果にスペースが入る。
 ファイルに出力も出来る。

print "a" "b" "c"  # abcと出力
print "a","b","c"  # a b cと出力
print "hoge" > "hoge.txt" # hoge.txtにhogeを出力
print "moge" >> "hoge.txt" # hoge.txtに追加出力

printf "%05d, %f, %s\n",10,1.2,"hoge"  # printと同様にファイルにも書き出せる。


 

AWKスクリプトの構造

BEGIN            { AWKの初期化処理 }
END              { AWKの終了処理 }

                 {各行の処理}

/正規表現/       {正規表現にマッチした行の処理}
!/正規表現/      {正規表現にマッチしなかった行の処理}
$n ~ /正規表現/  {$nが正規表現にマッチした行の処理}
$n !~ /正規表現/ {$nが正規表現にマッチしなかった行の処理}

match($0,/正規表現/,m) { 正規表現にマッチした行の処理。m[i]でグループを取得出来る }

変数宣言と型の種類

 変数宣言はない。初めて使ったところから存在し始める。

 文字列と数値と連想配列がある。文字列と数値にほぼ区別はない。
 未定義の変数は0か空文字と見なされる
 

AWKスクリプトの例:出現回数を求めて、値の和を求める

 例として今回の最初の課題、数数えてサイズ求めろ、というのを書いてみましょう。

 セル名が最初に、合計を取りたいサイズが最後に書いてあるログフォーマット(,区切り)だと仮定します。

BEGIN{FS=","}
{count[$1]++; size[$1]+=$NF;}
END{ for(n in count) printf "%s:count = %d, size = %f\n",n,count[n],size[n] }

 うーん、簡単。BEGIN{FS=","}は -F ","というコマンド引数でも可


 今時AWKで巨大スクリプトを書くなんてことはないでしょうが、ワンライナーとしては今でも十分強力ですね。
 昔はsortに渡す為に使ったりしたっけなぁ。