Python:解析带有各种字段数的冒号分隔文件

时间:2011-01-28 23:14:50

标签: python parsing file delimiter

我正在尝试使用'clientname'.txt

中的以下格式解析一些文件
hostname:comp1
time: Fri Jan 28 20:00:02 GMT 2011
ip:xxx.xxx.xx.xx
fs:good:45
memory:bad:78
swap:good:34
Mail:good

每个部分由a分隔:但是第0,2,6行有2个字段......第1,3-5行有3个或更多字段。 (我遇到麻烦的一个大问题是时间:行,因为20:00:02实际上是一个时间而不是3个单独的字段。

我有几个这样的文件需要解析。其中一些文件中有许多行包含多个字段。

...
for i in clients:
if os.path.isfile(rpt_path + i + rpt_ext):          # if the rpt exists then do this
    rpt = rpt_path + i + rpt_ext
    l_count = 0
    for line in open(rpt, "r"):
        s_line = line.rstrip()
        part = s_line.split(':')
        print part
        l_count = l_count + 1
else:                                               # else break
    break

首先我检查文件是否先存在,如果是,然后打开文件并解析它(最终)到目前为止我只是打印输出(打印部分)以确保它正确解析。 老实说,我现在唯一的麻烦就是时间:场。我怎么能把这条线与其他线特别不同?时间字段始终是我所有报告文件中的第二行。

4 个答案:

答案 0 :(得分:2)

split方法具有以下语法split( [sep [,maxsplit]]),如果给出maxsplit,则会使maxsplit + 1个部分。在你的情况下,你只需将maxsplit设为1.只需split(':',1)即可解决问题。

答案 1 :(得分:1)

如果time是特例,您可以这样做:

[...]
s_line = line.rstrip()
if line.startswith('time:'):
    part = s_line.split(':', 1)
else:
    part = s_line.split(':')
print part
[...]

这会给你:

['hostname', 'comp1']
['time', ' Fri Jan 28 20:00:02 GMT 2011']
['ip', 'xxx.xxx.xx.xx']
['fs', 'good', '45']
['memory', 'bad', '78']
['swap', 'good', '34']
['Mail', 'good']

并且不依赖于time在文件中的位置。

答案 2 :(得分:1)

设计考虑因素:

强健处理无关的空白,包括空行和缺少冒号。

提取一个record_type,然后用它来决定如何解析该行的其余部分。

>>> def munched(s, n=None):
...     if n is None:
...         n = 99999999 # this kludge should not be necessary
...     return [x.strip() for x in s.split(':', n)]
...
>>> def parse_line(line):
...     if ':' not in line:
...         return [line.strip(), '']
...     record_type, remainder = munched(line, 1)
...     if record_type == 'time':
...         data = [remainder]
...     else:
...         data = munched(remainder)
...     return record_type, data
...
>>> for guff in """
... hostname:comp1
... time: Fri Jan 28 20:00:02 GMT 2011
... ip:xxx.xxx.xx.xx
... fs:good:45
...     memory   :    bad   :   78
... missing colon
... Mail:good""".splitlines(True):
...    print repr(guff), parse_line(guff)
...
'\n' ['', '']
'hostname:comp1\n' ('hostname', ['comp1'])
'time: Fri Jan 28 20:00:02 GMT 2011\n' ('time', ['Fri Jan 28 20:00:02 GMT 2011'])
'ip:xxx.xxx.xx.xx\n' ('ip', ['xxx.xxx.xx.xx'])
'fs:good:45\n' ('fs', ['good', '45'])
'    memory   :    bad   :   78    \n' ('memory', ['bad', '78'])
'missing colon\n' ['missing colon', '']
'Mail:good' ('Mail', ['good'])
>>>

答案 3 :(得分:0)

如果时间字段始终为第2行。为什么你不能跳过它并单独解析它?

这样的东西
for i, line in enumerate(open(rpt, "r").read().splitlines()):
    if i==1: # Special parsing for time: line
        data = line[5:]
    else:
        # your normal parsing logic