我有一个json文件,我想更新' filename'带有文件名的字段我来自远程服务器的scp。我是python的新手,但我去学习。
JSON文件:
{"path":"/home/Document/Python",
"md5s":[{"filename":"",
"md5":"",
"timestamp":""},
{"filename":"",
"md5":"",
"timestamp":""},
{"filename":"",
"md5":"",
"timestamp":""}
]}
到目前为止我的python代码:
def filemd5():
try:
config = json.load(open(config_file))
#print(str(json.dumps(config, indent=4)))
for server in config['servers']:
ssh = SSHClient()
ssh.load_system_host_keys()
ssh.connect(server['ip'], username=server['username'],
password=server['password'])
#print(str(server))
print('Connecting to servers')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp/')
error = str(ssh_stderr.read())
if len(error) ==0:
for files in config['servers']:
filename = file_location + server['file']
scp = SCPClient(ssh.get_transport())
scp.get(filename)
if os.path.isfile(server['file']):
updateJsonFile(filename)
print(filename)
else:
print('KO')
def updateJsonFile(filename):
with open('md5.json', 'r') as f:
data = json.load(f)
subdata = data['md5s']
for check in subdata:
check["filename"] = filename
with open('md5.json', 'w') as f:
f.write(json.dumps(data))
filemd5()
格式化在这里并不是很好,但我几乎可以肯定它在我的python脚本中是好的。 现在发生的是它填充所有字段'文件名'当我是来自不同服务器的SCP三个文件时,使用相同的文件。
任何帮助都会很棒。感谢。
编辑(更新的问题,因为添加到文件可以工作,但它填充所有具有相同文件名的值。
预期结果:
{"path":"/home/Document/Python",
"md5s":[{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text2.txt",
"md5":"",
"timestamp":""},
{"filename":"text3.txt",
"md5":"",
"timestamp":""}
]}
实际值:
{"path":"/home/Document/Python",
"md5s":[{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text1.txt",
"md5":"",
"timestamp":""},
{"filename":"text1.txt",
"md5":"",
"timestamp":""}
]}}
答案 0 :(得分:1)
这就像我可以为你排序代码一样近。我不知道你为什么会KeyError
,但你没有按照评论中的建议实施一个计数器。由于我无法访问config['servers']
,因此计数器可能位于错误的位置,在这种情况下将其置于内部for
循环中。我在你的json字符串上对它进行了测试,它确实按照你的意图工作,所以原理是正确的,你只需要确保你传递counter
所需的值。
def filemd5():
try:
config = json.load(open(config_file))
counter = 0 # Add a counter here
for server in config['servers']:
ssh = SSHClient()
ssh.load_system_host_keys()
ssh.connect(server['ip'], username=server['username'],
password=server['password'])
print('Connecting to servers')
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp/')
error = str(ssh_stderr.read())
if not error:
for files in config['servers']:
filename = file_location + server['file']
scp = SCPClient(ssh.get_transport())
scp.get(filename)
if os.path.isfile(server['file']):
updateJsonFile(filename, counter)
counter += 1 # increment the counter
print(filename)
else:
print('KO')
except:
# I don't understand why you don't get an error for missing except?
pass
def updateJsonFile(filename, counter):
with open('md5.json', 'r') as f:
data = json.load(f)
subdata = data['md5s']
# The code below would update every value since you loop through whole list
#for check in subdata:
# check["filename"] = filename
subdata[counter]['filename'] = filename
with open('md5.json', 'w') as f:
f.write(json.dumps(data))
答案 1 :(得分:1)
如果我已经正确理解,你可以从包含文件引用列表的json文件开始,并且想要更新列表的下一个元素。
您可以浏览data['md5s']
搜索filename
字段为空的第一个元素,如果所有字段都已完成,则将新的字典添加到列表中:
def updateJsonFile(filename):
jsonFile = open("md5.json", "r") # load data from disk
data = json.load(jsonFile)
jsonFile.close()
for tmp in data["md5s"]: # browse the list
if len(tmp['filename']) == 0: # found one empty slot, use it and exit looop
tmp['filename'] = filename
break
else: # no empty slot found: add a new dict
data["md5s"].append({'md5': '', 'timestamp': '', 'filename': filename})
jsonFile = open("m.json", "w") # write the json back to file
json.dump(data, jsonFile)
jsonFile.close()