麗しき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問
以下のようなデータをa
とb
毎にまとめてみましょう。
$ 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さんが担当です!