如何在位于远程机器上的json文件中添加元素

时间:2017-11-21 12:35:25

标签: python json bash shell jq

我有一个位于远程计算机上的文件services.json

[
  {
    "kind": "SpecialService",
    "type": "attribute",
    "spec": {
      "addresses": [
        "172.21.3.196:6379"
      ]
    },
    "apiVersion": "rbac.newDevops.com/v1",
    "metadata": {
      "name": "redis",
      "description": "autogenerated by superagent.py script"
    }
  },
]

现在,任务是在json中附加以下元素的上述文件。

{
            "kind": "PilotService",
            "apiVersion": "rbac.newDevops.com/v1",
            "type": "attribute-based",
            "metadata": {
                "name": "apache",
                "description": "apache service as a process"
            },
            "spec": {
                "addresses": [
                    "172.22.0.7/24:80"
                ]
            }
}

一旦我们将内容添加到json文件中,我们需要关闭现有json的数组。 (文件内容以数组开头。)

我尝试使用python对远程计算机执行ssh但是我无法使用jqopen的python

在远程计算机上编辑json

关于这方面的任何指导,比如我们如何编辑远程机器上的json文件?

4 个答案:

答案 0 :(得分:2)

使用bash和进程替换(<(command)):

$ jq -s '.' <(jq '.[]' file1) file2
[
  {
    "kind": "SpecialService",
    "type": "attribute",
    "spec": {
      "addresses": [
        "172.21.3.196:6379"
      ]
    },
    "apiVersion": "rbac.newDevops.com/v1",
    "metadata": {
      "name": "redis",
      "description": "autogenerated by superagent.py script"
    }
  },
  {
    "kind": "PilotService",
    "apiVersion": "rbac.newDevops.com/v1",
    "type": "attribute-based",
    "metadata": {
      "name": "apache",
      "description": "apache service as a process"
    },
    "spec": {
      "addresses": [
        "172.22.0.7/24:80"
      ]
    }
  }
]

您可以将其用作file1的替换:<(ssh user@remote jq '.[]' file1)您只需设置ssh密钥以省略密码查询。这方面有很多指南。

答案 1 :(得分:1)

如果第一个文件是array.json和第二个object.json,那么忽略各种ssh / rsync / sponge选项,基本的jq调用将是这样的:

jq —-argfile object object.json ‘. + [$object]’ array.json

根据你的jq版本,有几个非常合理的选择。

假设要添加的对象不方便作为FILE或STDIN使用;据推测,它至少可以作为shell变量提供。在这种情况下,您可以按以下方式调整上述咒语:

jq —-argjson object "$object" ‘. + [$object]’ array.json

有关进一步的变化,请参阅jq manual

对于远程/本地的东西,假设jq在本地可用,也许你最好使用rsync将远程文件提取到本地,执行更新,然后rsync回到远程。有无数的变化,但我会把所有内容放在一个脚本中,这样你就可以轻松地添加改进来处理意外情况等。

答案 2 :(得分:0)

如果你能弄清楚如何以编程方式编辑文件,那么通过SSH完成它并不复杂,只需两步而不是一步。

import json

newdata = {
    "kind": "PilotService",
    "apiVersion": "rbac.newDevops.com/v1",
    "type": "attribute-based",
    "metadata": {
            "name": "apache",
            "description": "apache service as a process"
        },
    "spec": {
            "addresses": [
                "172.22.0.7/24:80"
            ]
    }

with open('services.json') as jdata:
    data = json.load(jdata)
data.append(newdata)
with open('services.json', 'w') as writable:
    writable.write(json.dump(data))

如果您可以在远程主机上保存此脚本,则只需

即可
ssh remote python script.py

但您可能希望使用Fabric或Paramiko来封装整个过程。

如果文件很大,您可能希望避免打开文件进行读取,读入内存,关闭,打开以进行写入,写入模式,但这通常是最简单的方法。 (您可以打开阅读和写作,并在阅读完毕后回放,但如果您有多个进程写入同一文件,那么这对于竞争条件并没有真正帮助。)

答案 3 :(得分:0)

所以最后通过尝试多个答案,我想发布问题的实际解决方案。

file1.json:

{
                "kind": "PilotService",
                "apiVersion": "rbac.newDevops.com/v1",
                "type": "attribute-based",
                "metadata": {
                    "name": "apache",
                    "description": "apache service as a process"
                },
                "spec": {
                    "addresses": [
                        "172.22.0.7/24:80"
                    ]
                }
}

file2.json:

[
  {
    "kind": "SpecialService",
    "type": "attribute",
    "spec": {
      "addresses": [
        "172.21.3.196:6379"
      ]
    },
    "apiVersion": "rbac.newDevops.com/v1",
    "metadata": {
      "name": "redis",
      "description": "autogenerated by superagent.py script"
    }
  },
]
shell终端上的

object=`cat file2.json`

jq --argjson object "$object" ". + [$object]" file1.json > beta.json