2012-05-12 77 views
2

我正在使用Python 3.我编写了两个程序。通过csv文件循环获取思科交换机的IP地址,登录,运行命令,并将结果输出到单个文本文件。所以我最终得到了许多文本文件......每个开关一个。第二个程序使用xlwt将每个文本文件中的信息写入Excel中自己的工作表。删除两个单词之间的所有字符并用空格替换

主要想法是我需要开发一个显示端口进出服务的报告。一旦我将这些导入到Excel中,我可以编写一些公式来提取我需要的数据。但现在,当我将它导入Excel时,我必须手动删除一些单元格,因为所有内容都不对齐,这是因为名称列中某些单词之间的空格(我正在导入到Excel中作为空间分隔)。我试图用字符串和列表方法(分割,连接,切片等)做一些事情,但我无法得到我想要的。名称列在任何一致的约定中都没有标准化。我注意到,虽然名称实际上可能非常长,但会被截断为一定数量的字符。理想情况下,删除前4行(最上面有空行)和最后一行,然后在端口和状态之间任意删除它(全部删除包括标题的列)。

这是从交换机获取数据后的文件显示方式。

 
sw1#term length 0 
sw1#show interfaces status 

Port  Name    Status  Vlan  Duplex Speed Type 
Gi0/1  Trunk to switch (a connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/2  Network augment pe connected 1   a-full a-1000 10/100/1000BaseTX 
Gi0/3      connected 1   a-full a-1000 10/100/1000BaseTX 
Gi0/4      connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/5      notconnect 1   auto auto Not Present 
Gi0/6      notconnect 1   auto auto Not Present 
Gi0/7      notconnect 1   auto auto Not Present 
Gi0/8      notconnect 1   auto auto Not Present 
Gi0/9      notconnect 1   auto auto Not Present 
Gi0/10      connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/11      notconnect 1   auto auto Not Present 
Gi0/12      connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/13      disabled  1   auto auto Not Present 
Gi0/14      disabled  1   auto auto Not Present 
Gi0/15      disabled  1   auto auto Not Present 
Gi0/16      disabled  1   auto auto Not Present 
sw1#logout 

最终结果我想在下面。这应该允许行/列结构在导入Excel时保持不变。请注意,所有列信息均以空格分隔。我发现导入为固定宽度或用空格分隔,连续空格作为一个对象进行检查似乎工作得很好。

 
Port  Status  Vlan  Duplex Speed Type 
Gi0/1  connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/2  connected 1   a-full a-1000 10/100/1000BaseTX 
Gi0/3  connected 1   a-full a-1000 10/100/1000BaseTX 
Gi0/4  connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/5  notconnect 1   auto auto Not Present 
Gi0/6  notconnect 1   auto auto Not Present 
Gi0/7  notconnect 1   auto auto Not Present 
Gi0/8  notconnect 1   auto auto Not Present 
Gi0/9  notconnect 1   auto auto Not Present 
Gi0/10 connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/11 notconnect 1   auto auto Not Present 
Gi0/12 connected 1   a-full a-100 10/100/1000BaseTX 
Gi0/13 disabled  1   auto auto Not Present 
Gi0/14 disabled  1   auto auto Not Present 
Gi0/15 disabled  1   auto auto Not Present 
Gi0/16 disabled  1   auto auto Not Present 

任何指针,将不胜感激。我认为正则表达式可能是有序的,但我需要一些帮助来构建它。我希望这不是太模糊。

除去以前的更新并移动到一个新的线程

+1

后的代码你有这么远。最初的想法是'split()'完全有能力处理这个;跳过索引'0'后的所有内容直到出现“连接|未连接|禁止”字样;之后,一切看起来相当符合我... –

回答

1
with open('file') as f: 
    lines = f.readlines() 
    lines = lines[-1:] + lines[2:-1] 
    for line in lines: 
     print line[0:11] + line[35:-1] 

我认为这会做大致是你想要的;你可能需要使用一些数字,因为我没有自己运行它。所有它采用的是列表(或字符串)索引:

  • 列表[X:]是所有条目从X起
  • 列表[X:Y]是从x到y的所有条目
  • 列表[ - x]是从结尾开始的第x行

lines[-1:] + lines[2:-1]将最后一行放在第一位,并丢弃前两位; line[0:11] + line[35:-1]不包括你不想要的部分和最终的换行符。

更新,如果你想写入到一个新的文件,而不是标准输出

with open('infile') as in: 
    with open('outfile', 'w') as out: 
     lines = in.readlines() 
     ... 
      print(line[0:6] + line[28:-1], file=out) 
其实

,因为readlines方法读取一次的一切,你可以这样做:

with open('infile') as in: 
    lines = in.readlines() 
with open('outfile', 'w') as out: 
    for line in lines: 
     .... 
     print(line[0:6] + line[28:-1], file=out) 

为输入文件不需要打开(当with完成时它会关闭)。

+0

这个作品也相当不错。对于我正在使用行打印(行[0:6] +行[28:-1])的文件很好。现在只需将其写入一个新文件即可。 – Shane

+0

请参阅写入文件的更新。 –

+0

工程很好。我不得不对索引进行一些修改,但我不知道为什么。对于我测试的每个更改,我都使用相同的输入文件。我怀疑它与我在打印到stdout时看到的\ n有关。在任何情况下,运行良好并删除文件的第一行和最后一行,并在Excel中正常工作。 – Shane

1

作为一个开始,下面的代码删除名称列。从那里拿出并添加一个不错的csv打印输出。建议:column[-1]是倒数第二项,column[-2]倒数第二项。如果字符串Not存在,请加入...

#!/usr/bin/env python 

tokens = ['connected', 'notconnect', 'disabled'] 

with open('text') as fd: 
    for line in fd: 
     line = line.strip().split() 

     connection = [line[0]] 
     found = False 

     for i in line: 
      if i in tokens: 
       found = True 
      if found: 
       connection.append(i) 

     print connection 

输出:评论后

['Gi0/1', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/2', 'connected', '1', 'a-full', 'a-1000', '10/100/1000BaseTX'] 
['Gi0/3', 'connected', '1', 'a-full', 'a-1000', '10/100/1000BaseTX'] 
['Gi0/4', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/5', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/6', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/7', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/8', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/9', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/10', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/11', 'notconnect', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/12', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/13', 'disabled', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/14', 'disabled', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/15', 'disabled', '1', 'auto', 'auto', 'Not', 'Present'] 
['Gi0/16', 'disabled', '1', 'auto', 'auto', 'Not', 'Present'] 

更新:

这是我如何使用KISS principle做到这一点:

#!/usr/bin/env python 

import sys 

tokens = ['connected', 'notconnect', 'disabled'] 

with open('text') as fd: 
    for line in fd: 
     line = line.strip().split() 

     connection = [line[0]] 
     found = False 

     for i in line: 
      if i in tokens: 
       found = True 
      if found: 
       connection.append(i) 

     if 'Not' in connection and 'Present' in connection: 
      # Remove last 2 entries 
      connection.pop() ; connection.pop() 
      connection.append('Not Present') 

     print connection 

输出:

['Gi0/1', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/2', 'connected', '1', 'a-full', 'a-1000', '10/100/1000BaseTX'] 
['Gi0/3', 'connected', '1', 'a-full', 'a-1000', '10/100/1000BaseTX'] 
['Gi0/4', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/5', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/6', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/7', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/8', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/9', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/10', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/11', 'notconnect', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/12', 'connected', '1', 'a-full', 'a-100', '10/100/1000BaseTX'] 
['Gi0/13', 'disabled', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/14', 'disabled', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/15', 'disabled', '1', 'auto', 'auto', 'Not Present'] 
['Gi0/16', 'disabled', '1', 'auto', 'auto', 'Not Present'] 
+0

我有你的解决方案工作,因为你已经解释,但当我尝试加入'不','礼物'我无法弄清楚。我可以做类似''.join(line [-2:])的东西,但我无法让它适用于所有行。此外,这可能是很明显的,我最终与'不存在',其他一切都删除。我已经尝试过循环和几次加入练习,所以它不是完全陌生的。我似乎无法重复您所做的删除名称列。你能给我另一个指针吗? – Shane

+0

@Shane - 已更新,对于迟到的回复感到抱歉! –

+0

谢谢你的时间。这很好。我学会了这么多,尽管我无法得到自己,但我会带走很多。我尝试了很多不同的东西。看到有很多方法可以用Python做事情真的很酷。顺便说一下,我正在考虑使用csv来整合您的解决方案,因为我发现当一些其他解决方案的组合取决于开关类型时,每个列中都有或多或少的字符需要处理。你的方法涉及到使用csv,所以我认为会更好。 – Shane

0

我们拿第一,最后5和价值观,做一个小的情况下开关,如果该类型不存在:

print "{:10} {:15} {:5} {:6} {:6} {}".format("port", "status", "vlan", "duplex", "speed", "type") 
with open(my_filename) as logfile: 
    content = logfile.read() 
    for line in content.splitlines()[4:]: 
     port = line.split()[0] 
     if line.strip().endswith("Not Present"): 
      itype = "Not Present" 
      status, vlan, duplex, speed = line.split()[-6:-2] 
     else: 
      status, vlan, duplex, speed, itype = line.split()[-5:] 
     print "{:10} {:15} {:5} {:6} {:6} {}".format(port, status, vlan, duplex, speed, itype) 

产量:

port  status   vlan duplex speed type    
Gi0/1  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/2  connected  1  a-full a-1000 10/100/1000BaseTX 
Gi0/3  connected  1  a-full a-1000 10/100/1000BaseTX 
Gi0/4  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/5  notconnect  1  auto auto Not Present 
Gi0/6  notconnect  1  auto auto Not Present 
Gi0/7  notconnect  1  auto auto Not Present 
Gi0/8  notconnect  1  auto auto Not Present 
Gi0/9  notconnect  1  auto auto Not Present 
Gi0/10  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/11  notconnect  1  auto auto Not Present 
Gi0/12  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/13  disabled  1  auto auto Not Present 
Gi0/14  disabled  1  auto auto Not Present 
Gi0/15  disabled  1  auto auto Not Present 
Gi0/16  disabled  1  auto auto Not Present 
1

我跳过前3行:

sw1#term length 0 
sw1#show interfaces status 

程序:

with open('in.txt') as f,open('out.txt','w') as out: 
    line1=f.readline() 
    ind1=line1.find('Name') 
    ind2=line1.find('Status') 
    x=line1.split() 
    x.remove('Name') 
    y="%-13s %-15s %-6s %-7s %-8s %-s"%(x[0],x[1],x[2],x[3],x[4],x[5]) 
    out.write(y+'\n') 
    for x in f: 
     x=x[:ind1]+x[ind2:] 
     x=x.split() 
     y="%-13s %-15s %-6s %-7s %-8s %-s"%(x[0],x[1],x[2],x[3],x[4],x[5]) 
     out.write(y+'\n') 


Port   Status   Vlan Duplex Speed Type 
Gi0/1   connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/2   connected  1  a-full a-1000 10/100/1000BaseTX 
Gi0/3   connected  1  a-full a-1000 10/100/1000BaseTX 
Gi0/4   connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/5   notconnect  1  auto auto  Not 
Gi0/6   notconnect  1  auto auto  Not 
Gi0/7   notconnect  1  auto auto  Not 
Gi0/8   notconnect  1  auto auto  Not 
Gi0/9   notconnect  1  auto auto  Not 
Gi0/10  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/11  notconnect  1  auto auto  Not 
Gi0/12  connected  1  a-full a-100 10/100/1000BaseTX 
Gi0/13  disabled  1  auto auto  Not 
Gi0/14  disabled  1  auto auto  Not 
Gi0/15  disabled  1  auto auto  Not 
Gi0/16  disabled  1  auto auto  Not 
+0

我一直在与这里提供的几种解决方案一起工作,但这一个我似乎能够复制并产生良好的结果。但我无法将结果写入文件。通常,并且因为这是我所知道的,所以我打开一个文件进行写入,并在f:f.write(line)中执行典型的行。或者该构造的一些迭代。我已经非常擅长打开现有文件并将其内容写入新文件。 在这种情况下,变量x包含我要写入文件的数据。因此,像我的行x:open('newfile','w')。write(x)? – Shane

+0

我很欣赏大家的反应,显然我是新手,但这对我来说是一个很好的学习机会。从迄今为止得到的建议,我看到我还有多少学习。 – Shane

+0

@Shane我编辑了解决方案,现在输出将被写入文本文件。 –

相关问题