我有这个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" } ]}
此python脚本正在读取此文件:
import json
import re
import sys
import unittest
import StringIO
def TestPorts(discoveryJson, spJson):
jsn = json.load(discoveryJson)
for dt in jsn['data']:
try:
id = dt['{#PROC_IDENT}']
port = dt['{#PROC_PORT_1111}']
spJson['data'].append({'{ID}': id, '{#PORT_1111}': port})
except Exception as err:
pass
def printTestPort(discFilespec, dumpDest=sys.stdout):
portJson = {'data': []}
try:
with open(discFilespec) as discJson:
TestPorts(discJson, portJson)
except:
pass
json.dump(portJson, dumpDest)
if __name__ == '__main__':
printTestPort('/tmp/file.json')
目前我只能在输出中打印一个端口值和id值:
{
"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代码中,我只能读取一个端口值,但我不知道如何实现,以便按进程id打印所有端口值。
例如:
{
"data": [
{
"{#ID}": "test1",
"{#PORT_1205}": "1205"
},
{
"{#ID}": "test2",
"{#PORT_442}": "442",
"{#PORT_2004}": "2004"
},
{
"{#ID}": "test3",
"{#PORT_4444}": "9001"
}
]
}
因此,如果修改了json文件,PORT值将自动更改。希望这次我能更清楚地解释一下。
答案 0 :(得分:1)
您需要更新循环中的{#PROC_PORT_1111}
密钥,以便在每次迭代时获取下一个端口(2222
,3333
,4444
等。我添加了一个incr
变量来跟踪它。还要编辑您的函数,以便在访问字典时使用get
:
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
如果您在print
分支中添加except
语句,您会注意到由于KeyError
,您的执行将会触发该分支两次。使用get
而不是[]
通常是一种更好的做法,因为前者从不抛出KeyError
而后者则抛出this
。
资源:dict.get
答案 1 :(得分:1)
当密钥{
"command": "extension.sayHello",
"title": "Say Hello",
"context": {
"where": "explorer/context",
"when": "json"
}
}
不存在时,您的原始代码抛出了KeyError,因此您无法捕获其他端口。这是一种方法 - 迭代项目;检查您是否对该项目感兴趣;按摩它;将它放在一个新容器中。
'{#PROC_PORT_1111}'
使用正则表达式。我正在使用regex module,因为它可以保存带有多个端口的进程所需的重复捕获
#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'}]}
>>>
答案 2 :(得分:1)
据我所知,我了解您的字段"{#PROC_PORT_2222}"
会随着数字而变化,即"{#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 ,那么请替换
行regex = r"{#PROC_PORT_[0-9]{4}}"
通过
regex = r"{#PORT_[0-9]{4}}"
P.P.S我认为将改变的数字将是4位数,如果没有,那么请在下面评论