更新已存在的json文件python

时间:2016-09-22 09:38:30

标签: python json

我有一个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":""}
 ]}}

2 个答案:

答案 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()