parse() is the opposite of format()
formatの逆をやって、template文字列からpythonの辞書などを作る方法というのがあると言うことを知った
複数行同士でマッチしたい
template.txtとresult.txtがあって、template.txtにある{}
の部分をまとめて辞書にしたい
ただし、result.txtは他の標準出力なども全部取り込んでおり、ある程度大きく、全体をtemplate.txtにするのは厳しいものとする
そうでなくても、例えば日付や実行時間のログのような、実行毎に変化する(けど、全部取得するほどは重要ではない)行などがある、とする
これまでだと、awkとかsedとか使ってシェルスクリプトでゴニョゴニョ・・・みたいに毎回半手作業で作っていたのを、もうちょっと楽ちんにしたいなぁという思い
やったこと
template.txtの各行をresult.txtの各行に畳み込みながらparseして、全行マッチするところを結合して取り出すようなイメージ
mapもreduceも、Noneが途中で出ても止まらないので、非常に無駄が多いが、性能をそこまで求めなければ・・・
(二重ループでぐるぐるして、みたいなのが上手くかけなかった・・・)
from parse import *
from parse import compile
def coerce_res(a, b):
try:
a.named.update(b.named)
a.fixed = a.fixed + b.fixed
return a
except:
return None
def match():
with open('template.txt', 'r') as ftemp, open('result.txt', 'r') as flog:
templines = ftemp.readlines()
# todo: remove leading & trailing blank lines from templines
loglines = flog.readlines()
for i in range(len(loglines) - len(templines) + 1):
a = map(lambda (x,y) : parse(x,y), zip(templines, loglines[i:]))
b = reduce(coerce_res, a)
if(b):
return b
print match()
# print fixed, named
サマリー的なものはだいたい最後にあるので最後からやったほうが早そう
欲しいもの
parseはformatの逆変換だが、例えばJinja2の逆変換みたいなものがあれば、使い手があるんじゃないかと思うのだが、そういうものはないだろうか?
実行時のログなどで、正確には何行出るかわからないような部分を{% for %}
みたいなもので記述して、リストなりで出力する、とか
失敗時のみ出るログを{% if %}
ブロックで囲んで置いて、失敗を検出する、とか
(因みにJinjaを使ったことがあるわけではないので、完全にイメージで言ってます)