2016-12-30 6 views
1

値出力値:印刷するすべてのポートは、私は、このJSONファイルを持っている

{ 
    "data": [ 
     { 
      "{#ID}": "test1", 
      "{#PORT_1111}": "1111" 
     } 
    ] 
} 

次の出力を得るにはどうすればよいですか? :

{ 
     "data": [ 
      { 
       "{#ID}": "test1", 
       "{#PORT_1111}": "1111" 
      }, 
      { 
       "{#ID}": "test2", 
       "{#PORT_2222}": "2222", 
       "{#PORT_3333}": "3333" 
      }, 
      { 
       "{#ID}": "test3", 
       "{#PORT_4444}": "4444" 
      } 
     ] 
    } 

あなたはそれを達成するために助けてくださいもらえますか?


私はもう一度明らかにする。

このJSONファイルは、ポートの値に向けて変更することができる:異なる値を有するポートの異なる量が有していてもよい

{ "data": [ { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test1", "{#PROC_ARGS}": "-l -c -g -k /etc/test1.conf", "{#PROC_PORT_1111}": "1111", "{#PROC_CONF}": "/etc/test1.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test2", "{#PROC_ARGS}": "-l -c -g -k /etc/test2.conf", "{#PROC_PORT_2222}": "2222", "{#PROC_PORT_3333}": "3333", "{#PROC_CONF}": "/etc/test2.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test3", "{#PROC_ARGS}": "-l -c -g -k /etc/test3.conf", "{#PROC_PORT_4444}": "4444", "{#PROC_CONF}": "/etc/test3.conf" } ]} 

したがって、各プロセスインスタンスの。たとえば、test1には1237の7000と1234のポート値test2のみ9004などがあります。

私のPythonコードでは、ポート値の1つのみを読み取ることしかできませんでしたが、プロセスidごとにすべてのポート値を出力する方法はわかりません。例えば

{ 
     "data": [ 
      { 
       "{#ID}": "test1", 
       "{#PORT_1205}": "1205" 
      }, 
      { 
       "{#ID}": "test2", 
       "{#PORT_442}": "442", 
       "{#PORT_2004}": "2004" 
      }, 
      { 
       "{#ID}": "test3", 
       "{#PORT_4444}": "9001" 
      } 
     ] 
    } 

だから、PORT値が自動的にJSONファイルの変更の場合は変更されます。今回私はより明確に説明しました。

+0

プロセスに複数のポートがある場合、それらは常にjsonデータに*表示されますか? – wwii

+0

@ user54、それはあなたの基準を明確に満たしているので私の答えをチェックアウト – penta

答えて

1

あなたの元のコードは、KeyError例外を投げましたこれを行う1つの方法があります。アイテムを繰り返し処理します。アイテムに興味があるかどうかを確認してください。それをマッサージ;新しい容器に入れて保管してください。正規表現を使用して

#setup 
import json, io 
from pprint import pprint 
s = """{ "data": [ { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test1", "{#PROC_ARGS}": "-l -c -g -k /etc/test1.conf", "{#PROC_PORT_1111}": "1111", "{#PROC_CONF}": "/etc/test1.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test2", "{#PROC_ARGS}": "-l -c -g -k /etc/test2.conf", "{#PROC_PORT_2222}": "2222", "{#PROC_PORT_3333}": "3333", "{#PROC_CONF}": "/etc/test2.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test3", "{#PROC_ARGS}": "-l -c -g -k /etc/test3.conf", "{#PROC_PORT_4444}": "4444", "{#PROC_CONF}": "/etc/test3.conf" } ]}""" 
f = io.StringIO(s) 

j = json.load(f) 
new_j = {'data' : []} 
for d in j['data']: 
    new_d = {} 
    new_d['{#ID}'] = d['{#PROC_IDENT}'] 
    for k, v in d.items(): 
     if k.startswith('{#PROC_PORT'): 
      k = k.replace('PROC_', '') 
      new_d[k] = v 
    new_j['data'].append(new_d) 


>>> pprint(new_j) 

{'data': [{'{#ID}': 'test1', '{#PORT_1111}': '1111'}, 
      {'{#ID}': 'test2', '{#PORT_2222}': '2222', '{#PORT_3333}': '3333'}, 
      {'{#ID}': 'test3', '{#PORT_4444}': '4444'}]} 
>>> 

。私はそれが複数のポートでプロセスのために必要とされる繰り返しキャプチャが保存されますので、私は数字と"{#PROC_PORT_2222}"変更あなたのフィールドと理解、私の知る限り

import json 
import regex 
from pprint import pprint 

pattern = r'{.*?(?P<id>"{#PROC_IDENT}"[^,]+).*?((?P<ports>"{#PROC_PORT_\d+}"[^,]+),\s?)+' 
r = regex.compile(pattern) 
# formatting string 
new_json = """{{ "data": [{} ]}}""" 
items = [] 

s = """{ "data": [ { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test1", "{#PROC_ARGS}": "-l -c -g -k /etc/test1.conf", "{#PROC_PORT_1111}": "1111", "{#PROC_CONF}": "/etc/test1.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test2", "{#PROC_ARGS}": "-l -c -g -k /etc/test2.conf", "{#PROC_PORT_2222}": "2222", "{#PROC_PORT_3333}": "3333", "{#PROC_CONF}": "/etc/test2.conf" }, { "{#PROC}": "/usr/local/test", "{#PROC_IDENT}": "test3", "{#PROC_ARGS}": "-l -c -g -k /etc/test3.conf", "{#PROC_PORT_4444}": "4444", "{#PROC_CONF}": "/etc/test3.conf" } ]}""" 
f = io.StringIO(s) 
data = f.read() 

#with open('s.txt') as f: 
# data = f.read() 

for m in r.finditer(data): 
    d = m.capturesdict() 
    d['id'][0] = d['id'][0].replace('PROC_IDENT', 'ID') 
    d['ports'] = [port.replace('PROC_', '') for port in d['ports']] 
    s = ','.join(thing for v in d.values() for thing in v) 
    items.append('{{{}}}'.format(s)) 

new_json = new_json.format(', '.join(items)) 
j = json.loads(new_json) 


>>> pprint(j) 
{'data': [{'{#ID}': 'test1', '{#PORT_1111}': '1111'}, 
      {'{#ID}': 'test2', '{#PORT_2222}': '2222', '{#PORT_3333}': '3333'}, 
      {'{#ID}': 'test3', '{#PORT_4444}': '4444'}]} 
>>> 
+0

私はどこでもヌル値を取得しています:( '{#PROC_PORT_1111}'はポート1111を印刷する試行に過ぎませんでしたが、私たちは2025ポートと1701 proc test1のように '{#PROC_PORT_PORT_NUMBER_HERE} "{#ID}": "test1"、 "{#PORT_2025}": "2025"、 "{#PORT_1701}": "1701"などの残りのpocess_idsについては、 – user54

+0

@ user54 - 私はあなたのコメントを理解していませんでした。私は答えを編集しました - あなたの後ろのものかどうかを確認してください。 – wwii

+0

@ user54 Pythonのどのバージョンを使用していますか? – wwii

1

は、あなたはそれがすべての繰り返しで次のポート(222233334444など)を取得するように、あなたのループ内{#PROC_PORT_1111}キーを更新する必要があります。私はそれを追跡するためにincr変数を追加しました。また、あなたが辞書にアクセスしている時はいつでもgetを使用するように機能を編集:あなたはexceptブランチでprint文を入れ

def TestPorts(discoveryJson, spJson): 
    jsn = json.load(discoveryJson) 
    incr = 1111; 
    for dt in jsn.get('data'): 
     try: 
      id = dt.get('{#PROC_IDENT}') 
      port = dt.get('{#PROC_PORT_' + str(incr) + '}') 
      spJson.get('data').append({'{ID}': id, '{#PORT_' + str(incr) + '}': port}) 
      incr += incr; 
     except Exception as err: 
      pass 

場合、あなたの実行が原因KeyErrorにその倍の枝をヒットすることがわかります。前者は決してKeyErrorを投げないので、getではなく[]を使用する方が良い方法ですが、後者はKeyErrorです。 。

リソース:あなたはキャプチャ他のポートではないことができるようにキー'{#PROC_PORT_1111}'が存在しないときdict.get

+0

申し訳ありませんが、動作しません。私は#PROC_PORTにnullの値を表示し、PROC_PORT_1111だけでなく、私も必要です。最後のjson出力に示されているように、他のポートも必要です。 – user54

+0

私は正しい答えを提供するために私の答えを編集しました。問題は、2222,3333などに増やすのではなく、ループの各反復で常に#PROC_PORT_1111の値を取得していたことです。 –

+0

努力してくれてありがとうございますが、残念ながらポート値が異なる。例:89、2001など。そのような変更の場合、修正が必要になるたびにコードは動的ではありません。 – user54

1

regex moduleを使用して、すなわち"{#PROC_PORT_XXXX}"ので、この中にしています文字列として"{#PROC_PORT_}"の文字列と一致する正規表現を使用する必要があります。

import re 
import json 

with open('s.txt') as data_file: 
    data = json.load(data_file) 

k = data['data'] 
regex = r"{#PROC_PORT_[0-9]{4}}" 

test_str = str(k) 
lst=[] 
matches = re.finditer(regex, test_str) 
for matchNum, match in enumerate(matches): 
    matchNum = matchNum + 1 
    lst.append("{match}".format(match=match.group())) 


for b in k: 
    for a in lst: 
     try: 
      print b[str(a)] 
     except: 
      pass 

s.txtは、jsonを持つtxtファイルです。

これにより出力が得られます。

1111 
3333 
2222 
4444 

P.S.あなたは、キーの名前を意味している場合だけPORTをPROC_PORTされていない場合、私がいない場合は変更される番号は、4桁になることが想定

regex = r"{#PROC_PORT_[0-9]{4}}" 

regex = r"{#PORT_[0-9]{4}}"

によってPPSの行を置き換え、以下にコメントしてください

+0

あなたの解決策はOPのものになりますか?いいえ、実際のデータを表していますか?所望の結果? – wwii

+0

はい、それを試してみましょう:-) – penta

+0

@wwii誰がOPですか? – penta

関連する問題