2017-01-23 17 views
0

readlines()を使用してPythonに54,000行のログをインポートしました。私は、サーバーの製造元とファームウェアのリビジョンを取得するために、ログからさまざまな行数を取得する必要があります。例えば、ここでログから3行である。Pythonで要素内の特定の要素と文字列を検索する

# 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のみログに1回発生します。 1台のサーバーから32台のサーバーにリストされています。このログを解析してiDRACのバージョンとサーバーのバージョンを取得し、ブレードクラス(self.iDRACself.model)のクラス属性に保存します。私がキャプチャする必要がある他のものがありますが、私はこの同じ概念を適用できるはずです。私が言って行を追加することができますどのように

(以下は、私の実際のコードだけ荒い例ではありません):

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

助けのため、実際の作業の入力を与える – Harvey

+0

質問はそれがあるべきほど有用ではないかもしれないが、私はこの時点で私のコードファイルにアクセスすることはできません。私は広範な説明を期待していたので、フラットな答えを得るのではなく、何かを助けてくれれば、自分で教えることができます。 – Dylan

答えて

0

あなたの質問は少し不明であるが、右のラインに沿ってこれのどこですか?

簡単に言えば、フィールドをタブまたは4つの連続するスペースで区切っているかどうかわからないので、正規表現(\s{4}|\t)で両方のケースを処理します。必要に応じてこれを変更することができます。

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) 

出力

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

これは絶対に私が入ってくる必要がある方向です。私たちは多くのブレードシャーシを扱い、さらに多くのブレードを扱います。最終的には、ストレージノードとスイッチ情報用のネットワークファブリック、BIOS、iDRACなどのファイルをキャプチャします。私はこれが私にそれを働かせるツールを与えると思う。 – Dylan

0

あなたは配列に各部分を区切るためにsplit()を使用することができ、この

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

のようなラインを持っていたら。デフォルトでsplit()は空白で文字列を区切ります。しかし、あなたの文字列に空白があるフィールドがいくつかあるようです。あなたを与える必要があり、ここでline.split("\t")

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

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

を使用すると、よりおよそsplit()hereを調べることができます(つまり、文字列が分離されている方法の場合)あなたは、タブの上にこのような何かを、それを分割することができます。

+0

ログにスペースが含まれていて、タブがないと言うのは間違いありません。私はsplit()を利用する必要があると思ったので、確認は素晴らしいです。各ブレードのself.iDRACへの保存は、私が実現する必要があるものですが、Tagcの提案が私に必要なものを与えるように見えます。 – Dylan

0

あなたはnextコールで適切なアイデアを持っています。リストのイテレータを作成し、for,nextまたはヘルプをitertoolsに入れて実行します。イテレータはその位置を覚えていますので、早期にループを抜けた場合は、次の項目から再スタートします。ここにはitertoolsの例がいくつかあります。 2番目はyield fromを使用しています。これはPython 3のものです。

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))) 
関連する問題