Skip to content

Instantly share code, notes, and snippets.

@kachick
Created May 22, 2012 05:26
Show Gist options
  • Select an option

  • Save kachick/2766820 to your computer and use it in GitHub Desktop.

Select an option

Save kachick/2766820 to your computer and use it in GitHub Desktop.
昔でっちあげたもの - ある形式のApacheログをCSV形式へ整えなおす
#!/usr/local/bin/ruby -w
# summarize Apache-access_log for a format
# Author: Kenichi Kamiya
# Release: 2011-10-25
# use: Ruby1.9.2
require 'forwardable'
require 'strscan'
require 'csv'
class Parser
extend Forwardable
FIELDS = [
:time,
:host,
:logname,
:username,
:request,
:statuscode,
:bytesize,
:unknown,
:useragent
]
def initialize(str)
@scanner = StringScanner.new str
end
def_delegators :@scanner, :eos?, :scan
def run
result = []
FIELDS.each do |type|
if data = __send__(:"parse_#{type}")
result << data
else
raise
end
trim_blank
end
trim_footer
eos? ? result : raise(@scanner.rest)
end
def parse_time
if scan(%r!\[(\d{2})/(\w{3})/(\d{4}):(\d{2}):(\d{2}):(\d{2}) \+0900\]!)
Time.local @scanner[3], @scanner[2], @scanner[1], @scanner[4], @scanner[5], @scanner[6]
end
end
def parse_host
if scan(/(\S+)/)
@scanner[1]
end
end
def parse_logname
if scan(/(\S+)/)
@scanner[1]
end
end
def parse_username
if scan(/(\S+)/)
@scanner[1]
end
end
def parse_request
if scan(/"(.+?)"/)
@scanner[1]
end
end
def parse_statuscode
if scan(/(\d{3})/)
@scanner[1]
end
end
def parse_bytesize
if scan(/(\d+)/)
Integer @scanner[1]
end
end
def parse_useragent
if scan(/"(.+?)"/)
@scanner[1]
end
end
def parse_unknown
if scan(/(\S+)/)
@scanner[1]
end
end
def trim_blank
scan(/ /)
end
def trim_footer
scan(/\n/)
end
end
ARGV.each do |path|
CSV.open "#{path}.csv", 'w', headers: Parser::FIELDS, write_headers: true do |csv|
File.foreach path do |line|
csv << Parser.new(line).run
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment