なんとなくawkつかってたが漸くすこし意味わかった件

アクセスログとか調べるときに

awk '{ print $1 }' | sort | uniq -c

とかやって、IPアドレスのカウントしたりしてたが、
awkの動きが全然わかってなかった。

この前CSVファイルをほげほげする機会があったので、awkの勉強をちょとした。

http://ja.wikipedia.org/wiki/AWK
awkすごい。

  • awkは渡されたファイルを一行ずつ処理する

100行のファイルを awk '{print $0}'とかやると100行出力される。

  • print
awk '{print $0}'

で一行がまるまる表示される。

    • $0

一行ぜんぶ

    • $1

1列目

    • $2

2列目


という具合。

  • デリミタ

デリミタはデフォルトでスペースのようだ。

abc def ghi hogehoge

これに対してawk printすると
$0はそのまま全部
$1はabc
$2はdef

  • if

grepを使えば条件に一致したものを簡単にだせるが
個人的にawkで便利なのが
あるカラムに対して不等号で条件かけるとこ。

hogehoge foo bar 1
hogehoge foo bar 0
hogehoge foo bar 3
hogehoge foo bar 2
hogehoge foo bar 5

というデータがあったとして

awk '{if($4 >= 1 ) print $0}'

こういう風にすれば、4つ目のカラムが1以上の場合のみ出力するという表示になる

awk '$4>=1{print$0}'<||
これでも同じ出力結果になるようだ。

  • BEGIN, END

構文

>

awk 'BEGIN{初期化処理}{させたい処理}END{最後にさせたい処理}'<||
コンストラクタ、デストラクタのような動きをつけることができる。

  • CSVを扱う上ではまったとこ

まずはデリミタを変更
awkのFS変数にいれてあげればよい。

awk 'BEGIN{FS=",";}{print $3;}'

これでカンマでわけた3列目のカラムだけ表示される。


さらに1以上である場合出力させたいとき

awk 'BEGIN{FS=",";}{if($3>=1) print $0;}'

見た目的にはこれでよさそうだが、なぜかできなかった・・・。
理由はCSVでわけられたファイルが

"hogehoge","foo","bar"

という風にダブルクォートでくくられていたからだった。
ので、

awk 'BEGIN{FS="\",\"";}{if($3>=1) print $0;}'

デリミタを","に変更。\でエスケープ。


awkおぼえてログをhogehogeできそう