読者です 読者をやめる 読者になる 読者になる

黒縁眼鏡は海を飛ぶ

IT中心にそこはかとなく

麗しきawkの世界

awkについて

この記事はShell Script Qiita Advent Calendar 2015の9日目の記事です。

12/8は@yudsuzukさんのiPhone7等の新製品を誰よりも早く予約する為に、予約サイトがオープンしたらSlackに通知する方法でした!

本記事ではテキスト処理時に凄まじい力を発揮するawkコマンドを僅かながら紹介したいと思います。
awkを使うと、特定のレコードやフィールドに対して様々な加工/整形/出力を行うことができます。
精通した方が使うとまるで魔法です。

知っていると大変便利ですので、是非お勉強しましょう!(そして私に教えてください。)

本記事ではGNU Awk 4.1.3を使用しています。 また、シェル芸勉強会の過去問を使用させていただいております。

四則演算とか

第10回シェル芸勉強会 1問

$ echo 1 2 3 4 5 | tr ' ' '\n' | awk '{a+=$1}END{print a}'
15

上記のようにパイプで与えられた各行について処理を行うことができます。
ENDのブロックはawkの処理の最後に実行されます。この場合は足し算の結果を出力しますね。


(連想)配列も扱えます

第17回ジュンク堂はシェル芸が乗っ取った勉強会 1問

以下のようなデータをab毎にまとめてみましょう。

$ cat data1
a 1
b 4
a 2
a 3
b 5
  
$ cat data1 | awk '{d[$1]=d[$1]" "$2}END{for(k in d){print k d[k]}}'
a 1 2 3
b 4 5

四則演算の例でも変数を使っていましたが、この例ではd連想配列を使用しています。
forはもちろん、ifだって使えます。


パイプを繋いでコマンドを実行できたり

第9回寒中シェル芸 6問

$ seq 1 100 | awk '{print "a"}' | tr '\n' '' | awk '{print "mkdir -p " $0}END{print "touch " $0 "b"}' | sh

色々なコマンドをつないだ結果を別のコマンドの引数として渡したい時にもawkは便利です。
上記では100階層までaディレクトリを作成し、最下層にbというファイルをtouchで作成します。
xargsもあわせて覚えると非常に便利です!


ログの整理も得意

# 5カラム目にhttp status codeがあると仮定して
$ cat access.log | awk '{print $0 > $5}'

エディタで開くだけでも重くて時間がかかるログファイルは事前に分割できると捗るかと思いますが、そんなときもawkが登場します。
例のように実行することでaccess.logステータスコード毎に分離できて分析が楽です。


便利な関数もあります

第10回シェル芸勉強会 3問

$ cat genkou
筆者は朝、目玉焼きを食べた。
昼、著者は卵がけごはんを食べた。
そして夜、著者はマンハッタンの夜景を
見ながらゆで玉子を食べた。

# genkouの文字数を数える
$ cat genkou | awk '{a+=length($1)}END{print a}'
61
# dateコマンドの結果から時間の部分を抽出
$ date +%Y%m%d-%H%M%S | awk -F '-' '{print substr($2,1,2)}'
# 時を操って定時退社する
$ date +%Y%m%d-%H%M%S | awk -F '-' '{sub(/[0-9]*/,180000,$2)}{print $2}'


シェル芸なワンライナーを例にawkを紹介させていただきましたが、いかがでしたでしょうか。 私の実力不足で紹介できた内容が薄っぺらなものになってしまいましたが、awkにはテキスト処理を行う上で有用な要素がたくさんあります。

awkを使いこなせるとシェル魔人達にささやかな抵抗が可能日々の何気無い業務が格段に楽になったりしますので、一緒にお勉強しましょう。


謝辞

テキストの遊園地
シェル芸とは
シェル芸勉強会問題一覧

明日10日目は@MasWagさんが担当です!