Python:解析具有不同字段计数的冒号分隔文件

Python:解析具有不同字段计数的冒号分隔文件,python,parsing,file,delimiter,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 每个部分都由:分隔,但其中第0,2,6行有2个字段。。。第1,3-5行有3个或更多字段。(我遇到的一个大问题是时间:行,因为20:00:02实际上是一个时间,而不是3个单独的字段 我有几个像这样的文件需

我正试图用“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
每个部分都由:分隔,但其中第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
首先,我先检查文件是否存在,如果存在,然后打开文件并解析它(最终),现在我只是打印输出(打印部分),以确保解析正确。
老实说,我现在唯一的问题是时间:字段。我如何处理这一行与其他行不同?时间字段始终是我所有报告文件中的第二行。

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

差不多

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

如果时间字段总是第二行,为什么不能跳过它并单独解析呢

差不多

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

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

split方法具有以下语法
split([sep[,maxsplit]]
如果给定maxsplit,它将使maxsplit+1个部分。在您的情况下,您只需将maxsplit设为1。只要
split(':',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']

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

如果
时间
是一个特例,您可以执行以下操作:

[...]
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']
并且不依赖于文件中时间的位置。

设计注意事项:

可靠地处理无关的空白,包括空行和缺少冒号

提取一个记录类型,然后用它来决定如何解析行的其余部分

>>> 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'])
>>>
设计注意事项:

可靠地处理无关的空白,包括空行和缺少冒号

提取一个记录类型,然后用它来决定如何解析行的其余部分

>>> 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'])
>>>


我必须跳过每一行超过1:delimiter的行,而那些超过1:delimiter的行并不总是在文件中的同一位置。我很难理解您试图实现的目标。您是否试图以不同的方式对待所有超过1:delimiter的行(时间:行除外)?我想解决办法是检查每一行的:,然后如果它有3个以上,则单独处理它?但不确定如何完成。我必须跳过每一行有1个以上的:delimiter,并且那些有1个以上的:delimiter的行并不总是在文件中的同一位置。我很难理解您试图解决的问题ccomplish。您是否尝试以不同的方式处理所有具有多个:的行(时间:行除外)?我认为解决方案是检查每一行的:,然后如果它具有多个:则单独处理它?不确定如何实现这一点。我起初尝试过,但在该行为Swap:Good:39的情况下,它会返回['Swap','Good:39']@Mark,如果date是导致此问题的唯一原因,那么您可以检查
如果line:part=s_line.split(':',1)
中的'time'。否则使用正常拆分。我一开始尝试过,但在Swap:Good:39行的情况下,它返回['Swap','Good:39']@Mark,如果date是唯一导致此问题的原因,那么您可以检查行中的'time'是否为'part=s_line.split(':',1)否则使用正常的拆分。太棒了,这样做了:)我想我的下一个问题是如何引用“new”字段的输出方式?也就是说,如果我下一步只想打印时间本身?是类似于第[1]部分还是第(1)部分?或者更具体地说,如何找出每个列表有多少字段?@Johnsyweb:如果有
超时:987
计时器:off
行,会发生什么情况?时间数据前面的前导空间是什么?最好是
if line.startswith('time:'))
,以防止“timers:foo:bar”被匹配。@John Machin:你必须在我开始键入时提交。我的答案得到了相应的更新。上面的示例中有一个前导空格。如果需要,可以删除它。太棒了,这样做了:)我想我的下一个问题是如何引用“new”字段的输出方式?也就是说,如果我下一步只想打印时间本身?是类似于第[1]部分还是第(1)部分?或者更具体地说,如何找出每个列表有多少字段?@Johnsyweb:如果有
超时:987
计时器:off
行,会发生什么情况?时间数据前面的前导空间是什么?最好是
if line.startswith('time:'))
,以防止“timers:foo:bar”匹配。@John Machin:你必须在我开始键入时提交。我的答案得到了相应的更新。上面的示例中有一个前导空格。如果需要,可以删除该空格。@Johnsyweb:YAGNI直接出自“著名的最后的话”。它忽略了墨菲定律的第256个推论:“如果用户、开发人员和头发尖尖的老板能够对数据布局进行特殊的更改,他们会的。”因此,我向上投票。但是,如果OP拥有数据和解析器,那么就没有更多的工作要做了。然而。@Johnsyweb:YAGNI直接出自“著名的遗言”。它忽略了墨菲定律的第256个推论:如果用户、开发人员和头发尖尖的老板能够对数据布局进行特殊的更改,他们会的。”因此,我向上投票。然而,如果OP拥有数据和解析器,那么就没有更多的工作要做了。然而。