我有一个位于远程计算机上的文件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但是我无法使用jq
或open
的python
关于这方面的任何指导,比如我们如何编辑远程机器上的json文件?
答案 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