Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

ログ管理 | LTSV | LTSVの簡易パーサーを作成してみた

概要

LTSVの簡易パーサー

詳細

LTSVの簡易パーサーを作成してみました。

仕様

・シェルから引数を指定しての呼び出しを想定
・オプションにkey:value形式で絞込み要素を指定
・valueは大文字小文字無視で絞り込まれる
複数の絞り込み内容を指定した場合はAND条件で絞る

※簡易パーサーのため対象ltsvファイルのサイズが大きいとあまりパフォーマンスが
よくありません。

実装コード
require_relative "./standard_io"
require_relative "./essentials"

module LtsvParser
  class Parser
    include StandardIo
    validate_file 0
    attr_accessor :ltsv, :args, :search_words
    PAIR = 2

    def initialize
      @ltsv = $*[0]
      filter_words = get_filter_words

      contents = open(@ltsv) do |f|
        f.each_line do |l|
          kv_maps = get_line_map l
          next unless output_target?(kv_maps, filter_words)
          puts l
        end
      end
    end

    private
    def output_target?(kv_maps, filter_words)
      ret = filter_words.each do |k, v|
        next unless kv_maps.has_key?(k)
        return false unless kv_maps[k].match /#{v}/i
      end
      true
    end

    def get_line_map(line)
      kv_map = {}
      line.split("\t").each do |kv|
        separete_index = kv.index(":")
        next unless separete_index

        key = kv.slice(0, separete_index)
        value = kv.slice(separete_index + 1 , kv.size).gsub(/[\[|\]]/, "").chomp
        kv_map[key.to_sym] = value
      end
      kv_map
    end

    def get_filter_words
      filter_words = {}
      filters.each do |fil|
        kv = fil.split(":")
        next unless (fil.count(":") + 1) == PAIR
        filter_words[kv[0].to_sym] = kv[1]
      end
      filter_words
    end

    def filters
      $*[1..-1]
    end
  end
end

ps = LtsvParser::Parser.new
exit unless ps.validate
standard_ioモジュールについて

下記記事参照
標準入出力処理時のValidationをクラスマクロで共通化
http://d.hatena.ne.jp/tbpg/20120325/1332656983

サンプル実行

対象ログLTSV:hoge.log
key1:value1_1	key2:value2_1
key1:value1_2_1	key2:value2_2_1
key1:value1_2_2	key2:value2_2_2
key1:value1_3	key2:value2_3
実行結果
$ruby ltsv_parser.rb hoge.log
key1:value1_1	key2:value2_1
key1:value1_2_1	key2:value2_2_1
key1:value1_2_2	key2:value2_2_2
key1:value1_3	key2:value2_3
$ruby ltsv_parser.rb hoge.log key1:2
key1:value1_2_1	key2:value2_2_1
key1:value1_2_2	key2:value2_2_2
$ruby ltsv_parser.rb hoge.log key1:2 key2:2_2_2
key1:value1_2_2	key2:value2_2_2