5
5

More than 5 years have passed since last update.

AWKで定義ファイルを元にデータファイルを処理する

Posted at

定義ファイル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,最近の情報
 :
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5