2017-01-23 3 views
0

Ich habe ein 54.000 Zeilenprotokoll in Python importiert, das readlines() verwendet. Ich muss eine variable Anzahl von Zeilen aus dem Protokoll ziehen, um Server-Make und Firmware-Revisionen zu erfassen. Zum Beispiel sind hier drei Zeilen aus dem Protokoll:Durchsuchen einer Liste in Python nach einem bestimmten Element und einer Zeichenfolge im Element

# racadm getversion 
<Server> <iDRAC Version>  <Blade Type>  <Gen> <Updatable> 
server-1 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 
server-2 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 

racadm getversion nur 1 Mal im Protokoll auftritt. Es kann irgendwo zwischen 1 Server und 32 Servern aufgeführt sein. Ich muss dieses Protokoll analysieren, um die iDRAC-Version und die Serverversion zu erfassen, und diese dann für die Klassenattribute für meine Blade-Klasse speichern (self.iDRAC, self.model). Es gibt noch andere Dinge, die ich erfassen muss, aber ich sollte in der Lage sein, dasselbe Konzept anzuwenden.

Wie könnte ich hinzufügen, eine Zeile (nach nicht mein eigentlicher Code ist nur ein grobes Beispiel) zu sagen:

if line in cmc.log == "# racadm getversion": 
    cmclist.next() 
    while line == "server-" 
     #do stuff to capture firmware 
+0

reale Arbeits Eingänge gibt Hilfe – Harvey

+0

die Frage nicht so hilfreich sein kann, wie es sein sollte, ich habe nur keinen Zugriff auf meine Code-Dateien zu diesem Zeitpunkt. Ich habe auf eine breitere Erklärung gehofft, damit ich mich selbst unterrichten kann, anstatt eine flache Antwort zu bekommen, wenn das irgendwie hilft. – Dylan

Antwort

0

Ihre Frage ein wenig unklar ist, aber das ist überall in der richtigen Richtung?

Als kurze beiseite, ich weiß nicht, ob Sie Felder mit Tabs oder vier aufeinander folgenden Leerzeichen abgrenzen, so behandle ich beide Fälle mit dem regulären Ausdruck (\s{4}|\t). Sie können dies ändern, wenn Sie brauchen.

import re 

DATA = \ 
"""<Server> <iDRAC Version>  <Blade Type>  <Gen> <Updatable> 
server-1 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 
server-2 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y""" 


class Blade(object): 
    def __init__(self, model, idrac): 
     self.model = model 
     self.idrac = idrac 

    def __repr__(self): 
     return 'Blade (model={}, idrac={})'.format(self.model, self.idrac) 


def parse_data(data): 
    for line in data.splitlines()[1:]: 
     model, idrac = re.split(r'(\s{4}|\t)', line)[:2] 
     yield Blade(model, idrac) 


if __name__ == '__main__': 
    for blade in parse_data(DATA): 
     print(blade) 

Ausgabe

Blade (model=server-1, idrac=1.57.57 (Build 04)) 
Blade (model=server-2, idrac=1.57.57 (Build 04)) 
+0

Das ist absolut die Richtung, in die ich mich bewegen muss. Wir behandeln viele Blade-Chassis und im Nachhinein viele Blades. Letztendlich werden Netzwerkstrukturen, BIOS, iDRAC und ähnliche Dateien für Speicherknoten und Switch-Informationen erfasst. Ich denke, das wird mir die Werkzeuge geben, damit es funktioniert. – Dylan

0

Sobald Sie eine Zeile wie diese

haben
server-1 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 

können Sie split() verwenden, um jedes Teil aus einem Array zu trennen. Standardmäßig trennt split() die Zeichenfolge durch Leerzeichen. Es sieht jedoch so aus, als ob Ihre Zeichenfolge einige Felder enthält, die Leerzeichen enthalten. Sie es über einen Reiter aufgeteilt könnten (wenn das ist, wie der String getrennt ist) so etwas wie diese:

for line in cmclist: 
    separated=line.split("\t") 
    version=separated[1] 

hier line.split("\t") sollen Sie:

["server-1", "1.57.57 (Build 04)", "PowerEdge M620", "iDRAC7", "Y"] 

Sie mehr über split()here nachschlagen können.

+0

Sie haben richtigerweise gesagt, dass das Protokoll Leerzeichen und keine Tabulatoren enthält. Ich dachte mir, dass ich am Ende split() nutzen müsste, also ist die Bestätigung ausgezeichnet. Das Speichern auf self.iDRAC für jeden Blade muss etwas passieren, aber es sieht so aus, als ob der Vorschlag von Tagc mir geben würde, was ich brauche. – Dylan

0

Sie haben die richtige Idee mit dem next Anruf. Erstellen Sie einen Iterator für die Liste und verwenden Sie dann for, next oder Helfer in itertools, um durch sie zu laufen. Iteratoren merken sich ihre Position. Wenn Sie also früh aus einer Schleife aussteigen, werden sie beim nächsten Element neu gestartet. Hier sind ein paar Beispiele mit itertools. Der zweite verwendet yield from, was eine Sache mit Python 3 ist.

import itertools 

cmclog = """other stuff 
other stuff 
# racadm getversion 
<Server> <iDRAC Version>  <Blade Type>  <Gen> <Updatable> 
server-1 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 
server-2 1.57.57 (Build 04)  PowerEdge M620 iDRAC7  Y 
other stuff 
other stuff""".split("\n") 

def scan_server_list(cmclog): 
    server_list = [] 
    icmc = iter(cmclog) 
    try: 
     # drop everything through the racadm sentinal 
     next(itertools.dropwhile(
      lambda line: not line.startswith("# racadm getversion"), 
      icmc)) 
     # skip header 
     next(icmc) 
     # take all servers 
     server_list.extend(itertools.takewhile(
      lambda line: line.startswith("server-"), 
      icmc)) 
    except StopIteration: 
     pass 
    return server_list 

print(scan_server_list(cmclog)) 

def scan_server_list_2(cmclog): 
    icmc = iter(cmclog) 
    # drop everything through the racadm sentinal 
    next(itertools.dropwhile(
     lambda line: not line.startswith("# racadm getversion"), 
     icmc)) 
    # skip header 
    next(icmc) 
    # take all servers 
    yield from itertools.takewhile(
     lambda line: line.startswith("server-"), 
     icmc) 

print(list(scan_server_list_2(cmclog))) 
Verwandte Themen