Skip to content

Instantly share code, notes, and snippets.

@ishideo
Last active February 1, 2018 11:36
Show Gist options
  • Save ishideo/9931a6fc28f9bb1dd3f9beab9a02418a to your computer and use it in GitHub Desktop.
Save ishideo/9931a6fc28f9bb1dd3f9beab9a02418a to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
# ruby log_extractor.rb --in_csv "./abc.csv" --in_time_column "2" --in_value_column "3" --in_skip_lines "0" --out_time_column_format "%Y/%m/%d %H:00:00" --interval "5" --begin_date "20xx/xx/xx" --duration "month"
require 'csv'
require 'date'
require 'optparse'
require 'time'
class LogExtractor
def initialize
params = optparse
@in_csv = params['in_csv'].encode('UTF-8')
@in_time_column = if params['in_time_column'] =~ /^(|[1-9]\d*)$/
params['in_time_column'].to_i
else
params['in_time_column'].to_s
end
@in_value_column = if params['in_value_column'] =~ /^(|[1-9]\d*)$/
params['in_value_column'].to_i
else
params['in_value_column'].to_s
end
@in_skip_lines = params['in_skip_lines'].to_i
@out_time_column_format = params['out_time_column_format']
@interval = params['interval'].to_i * 60
@begin_date = params['begin_date']
@duration = params['duration']
@csv_done = @in_csv.sub(/csv/, 'csv_done')
print_log
save_csv
end
def optparse
params = ARGV.getopts('', 'in_csv:', 'in_time_column:', 'in_value_column:',
'in_skip_lines:0',
'out_time_column_format:%Y/%m/%d %H:%M:%S',
'interval:60', 'begin_date:', 'duration:')
params
end
def save_csv
dates = create_dates_by(@begin_date, @interval, @duration)
log = hash_log @in_csv, @in_time_column, @in_value_column, @in_skip_lines
rows = dates.map do |x|
[Time.parse(x).strftime(@out_time_column_format), log[x]]
end
CSV.open(@csv_done, 'w', encoding: 'UTF-8') do |csv|
rows.each do |row|
csv << row
end
end
end
def print_log
puts 'in_csv: ' + @in_csv
puts 'in_time_column: ' + @in_time_column.to_s
puts 'in_value_column: ' + @in_value_column.to_s
puts '--------------------------------------------------'
end
def hash_log(csv, time_column, value_column, skip_lines)
dates = open_csv csv, time_column, skip_lines
values = open_csv csv, value_column, skip_lines
dates.map(&method(:round_date)).zip(values).to_h
end
def round_date(str)
min = str[str.length - 4].to_i
return str[0..str.length - 5] + '5:00' if min >= 5 && min < 10
str[0..str.length - 5] + '0:00'
end
def create_dates_by(date, sec, duration)
t = Time.parse(date)
end_day = Date.new(t.year, t.month, -1).strftime('%Y/%m/%d')
date_year = (Date.new(t.year, t.month, 1) << 5).strftime('%Y/%m/%d')
begin_time = date_year + ' 00:00:00' if duration == 'year'
begin_time = t.strftime('%Y/%m/%d') + ' 00:00:00' if duration == 'month'
end_time = end_day + ' 23:55:00'
from = Time.parse(begin_time).to_i
to = Time.parse(end_time).to_i
from.step(to, sec)
.map { |m| Time.at(m).strftime('%Y/%m/%d %H:%M:%S') }
end
def create_times_by(sec)
inc = sec.to_i
from = Time.parse('00:00').to_i
to = Time.parse('23:55').to_i
from.step(to, inc)
.map { |m| Time.at(m).strftime('%H:%M:%S') }
end
def integer?(str)
Integer(str)
true
rescue ArgumentError
false
end
def open_csv(file, col, skip_lines)
csv = CSV.read(file).drop(skip_lines)
if integer?(col)
index = col - 1
csv.map { |e| e[index] }
else
csv_header = CSV.new(
csv.map(&:to_csv).join(''), headers: true
)
table = csv_header.read
table[col]
end
end
end
LogExtractor.new if $PROGRAM_NAME == __FILE__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment