匹配大日志文件中的两行并显示它们之间的内容

时间:2015-05-17 13:33:02

标签: python regex perl awk sed

我有一个很大的日志文件,有很多事情要发生。所需要的是在日志文件中的两行之间获取内容。

示例:

----------------------------------------
-- ServiceDataBlock (SDB):{MO}:
  > From channel# ..... [111]
  > (Orig)Ton, TP_OA .. [91][1234567891234]
  > (Dest)Ton, TP_DA .. [A0][12345]
  > TP_PID, TP_DCS .... [00][00]
  > TP_SCTS ........... []
  > TP_UserDataHdr .... []
  > TP_UserData ....... {3}[yes]
----------------------------------------

-- ServiceDataBlock (SDB):{MO}:> TP_UserData ....... {3}[yes]之间的内容是动态的。

我想在中间只提取(Orig)Ton, TP_OA .. [91][1234567891234]TP_UserData ....... {3}[yes]: - )

请注意,还有许多其他内容已定义相同-- ServiceDataBlock (SDB):{MO}:,但块中没有TP_UserData ....... {3}[yes]

有人可以帮忙吗?我尝试使用正则表达式,grep,sed和awk。

我需要CSV或Excel格式的输出。

3 个答案:

答案 0 :(得分:1)

下面是一个简单的基于状态的解析器。它没有经过充分测试,可能会对日志文件的格式做出一些不正确的假设。不过,它应该可以帮助您入门。

def process_log(path):
    contents = []
    with open(path) as stream:
        state = 0
        line = ''
        block = None
        while line is not None:
            try:
                if not line:
                    line = next(stream)
            except StopIteration:
                line = None
            else:
                line = line.strip()
                if state == 0:
                    if line.startswith('-- ServiceDataBlock'):
                        block = []
                        state = 1
                    line = ''
                    continue
                elif state >= 1:
                    if line.startswith('>'):
                        line = line.lstrip('> ')
                        if not line.startswith('From channel#'):
                            block.append(line)
                            if line.startswith('TP_UserData '):
                                state = 2
                        line = ''
                        continue
            if state == 2:
                contents.append(block)
            state = 0
    return contents

答案 1 :(得分:0)

谢谢大家。

我知道我不希望这里有一个现成的代码: - )

以下是我使用grep实现的: - )

grep -Po "(.*Orig.*\[(234.*)\])\n(.*)\n(.*)\n(.*)\n(.*)\n(.*yes.*)" filename

这实际上可以帮助我获取数据,我已经做了更多的事情来获取确切的东西,但现在可以使用。

完成后我会发布完整的答案。

再次感谢!

答案 2 :(得分:0)

perl方式:

perl -ane 'print if /-- ServiceDataBlock/ .. /TP_UserData /' filename