定義ファイルAを元にデータファイルBを処理したいということがあります。
結論をいうと
$ awk -f proc.awk file_a file_b
とやって、proc.awk
の処理の中でFILENAME
変数によって処理を分離して上げればいいようです。
動作確認環境
- awk : GNU awk 4.0.1
kwsk
define.csv
index index
cart 買い物画面
info 最近の情報
ticket 割引券
access.log
2014-04-01.09:10:00.05 ip-XX.XX.XX.12 /index
2014-04-01.09:10:01.25 ip-YY.YY.YY.5 /info/123?q=winter
2014-04-01.09:10:01.31 ip-ZZ.ZZ.ZZ.12 /ticket/ski-items/201412
2014-04-01.09:10:03.00 ip-YY.YY.YY.5 /info/3323?date=20140320&page=3
:
上のaccess.logをプロセスして、時間と画面名のみのCSVファイルが最終的にほしい、なんてことがあります。
Excelのvlookupを使ったり、shellやrubyなどのLL言語で処理を書いてもいいんですが、AWKを使って実現させるのが処理の早さ的にも、実装の簡単さ的にも一番良さそう。
proc.awk
# triming space or tab
function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s }
function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
function trim(s) { return rtrim(ltrim(s)); }
# get page-name in url
function page_name(s) {
sub(/^\//,"",s)
sub(/\/.*$/,"",s)
return s
}
# 定義の取得して配列に格納
FILENAME == "define.csv" {
def[$1] = $2
}
# データのプロセス
FILENAME == "access.log" {
page = page_name(trim($3))
print $1 "," def[page]
}
$ wc access.log
401408 1204224 23382016 access.log
$ time awk -f proc.awk define.csv access.log > proc.log
real 0m1.761s
user 0m1.727s
sys 0m0.034s
$ head proc.log
2014-04-01.09:10:00.05,index
2014-04-01.09:10:01.25,最近の情報
2014-04-01.09:10:01.31,割引券
2014-04-01.09:10:03.00,最近の情報
: