Python 打印所有端口值
我有这个json文件:Python 打印所有端口值,python,json,Python,Json,我有这个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}":
{ "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文件时自动更改。希望这次我解释得更清楚。您需要更新循环中的
{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
而不是[]
通常是一种更好的做法,因为前者从不抛出键错误,而后者则抛出
资源:当密钥'{PROC_PORT_1111}'不存在时,您的原始代码抛出了一个密钥错误,因此无法捕获其他端口。这里有一种方法——迭代项目;查看您是否对该项目感兴趣;按摩它;把它放在一个新的容器里
#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'}]}
>>>
使用正则表达式。我之所以使用,是因为它可以保存具有多个端口的进程所需的重复捕获
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'}]}
>>>
导入json
导入正则表达式
从pprint导入pprint
pattern=r'{.*?(?P“{PROC#u IDENT}”[^,]+).*(?P“{PROC#u PORT\ud+}”[^,]+),\s?+'
r=regex.compile(模式)
#格式化字符串
new_json=“”{{“数据”:[{}]}”“”
项目=[]
“数据:”“““{”数据:“{”数据:“{”数据:“{”数据:“{”数据:“{”数据:“{”数据:“{”数据:““{”数据:“““{”数据:”““{”数据:““{”数据:“{”数据:“““{”数据:“{”数据:“{”数据:“{”数据:“{”数据:“““““““““{”数据”数据”数据:““““““““““,”””””””““““““““““{”数据”数据”数据:“““““““““::::::::::---l-l-l-l-l-l-l-l-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-c-g-g-g-g-g-g-g-"PROC#u ARGS":“-l-c-g-k/etc/test2.conf”、“{PROC#u PORT_2222}”:“2222”、“{PROC#u 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#port4444}”:“4444”,“{PROC#ARGS}”:“test3”;“{
f=io.StringIO(s)
data=f.read()
#将open('s.txt')作为f:
#data=f.read()
对于r.finditer中的m(数据):
d=m.capturesdict()
d['id'][0]=d['id'][0]。替换('PROC_IDENT','id')
d['ports']=[port.replace('PROC_','')用于d['ports']]中的端口
s=','.join(d中的v的thing.v中的thing的value())
items.append({{}}.format)
new_json=new_json.format(','.join(项目))
j=json.loads(新的_-json)
>>>pprint(j)
{'data':[{'ID}':'test1',{'PORT#u 1111}':'1111},
{{{ID}:'test2',{{PORT{2222}:'2222',{PORT{3333}:'3333},
{{{ID}:'test3',{{PORT}:'4444}]}
>>>
据我所知,我了解您的字段“{code>随着数字的变化而变化,即“{PROC#u PORT_XXXX}”
,因此在这种情况下,我们需要使用regex来匹配作为固定字符串的任何字符串
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.如果您的意思是密钥名称只是端口而不是进程端口,请替换该行
regex = r"{#PROC_PORT_[0-9]{4}}"
借
regex=r“{#端口{0-9]{4}”
p.p.S我假设将要更改的数字是4位数字,如果不是,请在下面发表评论抱歉,但它不起作用。它为#PROC_端口打印空值,我不仅需要PROC_端口_1111。我还需要上一次json输出中显示的其他端口。我已经编辑了我的答案,以提供正确的解决方案问题是,在循环的每次迭代中,您总是得到#PROC_PORT_1111的值,而不是将其增加到2223333等。感谢您的努力,但不幸的是,只要端口值可能不同,它就没有意义。例如:89、2001等。因此,在这种情况下,只要每次我需要更正它。如果您在附加到spJson之前不知道端口值,您可以在之前读取一次该文件,以获取所有不同的端口值并将其填充到列表中。然后,您可以解析json,对于该列表中的每个端口值,获取其值,并附加到spJson。我在任何地方都会得到空值:('{#PROC#u PORT_1111}只是打印端口1111的一个尝试。但是我需要某种方式来让脚本自动确定{#PROC#u PORT_PORT_PORT_NUMBER_HERE}例如,如果我们有2025端口和1701用于PROC test1,它将“{#ID}”:“test1”,“{#PORT#u 2025}”:“2025”,“2025”,“1701”:“1701”"。等等。对于其余的pocess_ID,如我请求的最后一个输出中所示。端口可能完全不同,它们的数量也可能不同。@user54-我不理解您的评论。我编辑了答案-看看这是否是您想要的。您的示例json数据真的代表了实际数据吗?-如果不是,请e在您的问题中提供一小部分实际的json数据。@user54您使用的是哪一版本的Python?您的解决方案是否会构造OP所需的结果?@wwii谁是OP?原始PosterIf一个进程有多个端口,它们是否总是按顺序显示在json数据中?@user54,请检查我的答案,因为它显然满足您的标准ia