jq - 向子项添加字段,打印父项

jq - Add field to child, print parent

问题:从 json 文件中,从磁盘读取它并向子对象添加一个字段并将其打印回磁盘。

文件:

{
  "name": "api",
  "script": "index.js",
  "instances": "1",
  "env": {
    "PORT": 3000
  },
  "env_production": {
    "PORT": 3000
  }
}

所以我设法通过管道传输并添加字段:

cat pm2.json | jq --arg key val '. as $parent | .env_production + {"abc": "123"}'

其中 returns 添加了字段的子对象。但是,我需要更新磁盘上的文件。所以我还需要打印整个对象(父对象)。

我可以通过打印 $parent 变量来做到这一点。但我无法让它工作,因为它是不可变的。

cat pm2.json | jq --arg key val '. as $parent | .env_production + {"abc": "123"}| $parent'

问题:如何才能使 $parent 变量具有新添加的字段,以便我可以将其通过管道返回到原始文件?

像这样使用 spongejq 怎么样:

jq '.env_production.abc = "123"' pm2.json | sponge pm2.json

上述命令会将 abc: "123" 附加到 env_production 键,输出(完整的 json 对象)将传递给 sponge 以更新文件

sponge is a part of moreutils package

sponge 根据它在手册页中的描述比 shell 重定向有优势:

sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before opening the output file. This allows constricting pipelines that read from and write to the same file.

此处使用的最佳工具是更新加法运算符,+=

< pm2.json jq '.env_production += {"abc": "123"}'

会输出

{
  "name": "api",
  "script": "index.js",
  "instances": "1",
  "env": {
    "PORT": 3000
  },
  "env_production": {
    "PORT": 3000,
    "abc": "123"
  }
}

结果类似于

. + {"env_production": (.env_production + {"abc":"123"})}

除了它当然要简单得多:)