2012-05-12 76 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我編輯瞭解決方案,現在輸出將被寫入文本文件。 –

相關問題