Pythonic解析表?

时间:2015-01-09 17:01:50

标签: python parsing

我有一张这样的桌子,会增长和缩小: 它当然包括标签,新行等。这是一个字符串。

Interface        group           vlan    ver                                                          
fa1/6            239.0.0.3       2       2                                                            
fa1/2            239.0.0.1       1       2     
fa1/1            239.0.0.0       3       2
fa1/6            239.0.0.1       1       2

我想以格式

解析它
vlan  ports
----  -----
   1  fa1/2, fa1/6  
   2  fa1/6
   3  fa1/1

然而,我这样做的方式非常混乱,我觉得有更多的字符串操作比我需要的更多,分裂,排序等等。你们会用什么方法?

2 个答案:

答案 0 :(得分:2)

尝试pandas

import pandas as pd
from StringIO import StringIO

s = """Interface        group           vlan    ver                                                          
fa1/6            239.0.0.3       2       2                                                            
fa1/2            239.0.0.1       1       2     
fa1/1            239.0.0.0       3       2
fa1/6            239.0.0.1       1       2"""
header = "vlan    ports\n----    -----\n"

现在你可以做到:

>>> df = pd.read_csv(StringIO(s), delim_whitespace=True)\
           .groupby('vlan')['Interface']\
           .apply(lambda x: ', '.join(x))
>>> print(header + df.to_string())
vlan    ports
----    -----
1       fa1/2, fa1/6
2              fa1/6
3              fa1/1

答案 1 :(得分:1)

三步法:

  1. 将文本行转换为字典数组
  2. 遍历字典数组,将您想要的信息组合在一起创建另一个字典。
  3. 将结果字典打印为表格。
  4. 示例:

    foo="""Interface        group           vlan    ver  
    fa1/6            239.0.0.3       2       2
    fa1/2            239.0.0.1       1       2
    fa1/1            239.0.0.0       3       2
    fa1/6            239.0.0.1       1       2
    """
    
    def parse_lines(lines):
      headers = lines[0].split()
      entries = []
      for r in lines[1:]:
        if not len(r): continue    # skip blank lines
        vals = r.split()
        e = dict(zip(headers,vals))
        entries.append(e)
      return entries
    
    def doit():
      entries = parse_lines(foo.split("\n"))
      ports = {}
      for e in entries:
        vlan = e["vlan"]
        if not (vlan in ports): ports[vlan] = []
        ports[vlan].append( e["Interface"] )
      print "%6s %s" % ("vlan", "ports")
      for vlan in ports:
        print "%6s %s" % (vlan, ', '.join(ports[vlan]))
    
    doit()