jq 不向 json 文件注入值

jq doesn't inject value into the json file

我有 json 文件 env.json 具有以下内容:

{
  "parameters": {
    "name": "www",
    "dev" : "",
    "prod": ""
  }
}

现在我想使用 jq 通过 bash 脚本注入 devprod 的值。这是代码:

  ENVJSON=$(cat env.json)
  jq '.parameters.name = $val' --arg val $NAME <<<"$ENVJSON" > env.json
  jq '.parameters.prod = $val' --arg val $PROD <<<"$ENVJSON" > env.json
  jq '.parameters.dev = $val'  --arg val $DEV  <<<"$ENVJSON" > env.json

当我 运行 这样做时,我将 $NAME 和 $DEV 的值正确地注入到 JSON 文件中。但是 $PROD 值不会为 prod 索引注入。它保持为空。看起来这是中间线的问题。

如果我交换最后两行,那么是的,中间的行不起作用。

这里可能有什么问题?


我也试过在每个 jq 命令的末尾附加 && sleep 1,但没有成功。

您可以用 jq 进行 multi-value 替换,以防止一次又一次地覆盖同一个文件。

#!/usr/bin/bash
NAME=name
DEV=dev
PROD=prod
echo -e "$(jq --arg name $NAME --arg dev $DEV --arg prod $PROD '.parameters.name = ($name) | .parameters.dev = ($dev) | .parameters.prod = ($prod)' env.json)" > env.json

如果 JSON 模板从不更改,则不需要从文件中读取它。该模板包含在采用 --null-input-njq 过滤器脚本中,因此它可以直接写入输出文件,而无需保存到中间临时文件。

NAME='www foo' PROD='prod bar thing' DEV='stuff for dev baz'
jq -n --arg name "$NAME" --arg prod "$PROD" --arg dev "$DEV" \
  '{"parameters":{"name":$name,"dev":$dev,"prod":$prod}}' > env.json

cat env.json:

{
  "parameters": {
    "name": "www foo",
    "dev": "stuff for dev baz",
    "prod": "prod bar thing"
  }
}

其他答案都很好,但我犯了一个愚蠢的错误,我想指出。在这些命令中,

  ENVJSON=$(cat env.json)
  jq '.parameters.name = $val' --arg val $NAME <<<"$ENVJSON" > env.json
  jq '.parameters.prod = $val' --arg val $PROD <<<"$ENVJSON" > env.json
  jq '.parameters.dev = $val'  --arg val $DEV  <<<"$ENVJSON" > env.json

我在这些命令中的每一个中都使用了相同的输入,而不是更新的命令。所以我改成了:

  jq '.parameters.name = $val' --arg val $NAME <<<"$(cat env.json)" > env.json
  jq '.parameters.prod = $val' --arg val $PROD <<<"$(cat env.json)" > env.json
  jq '.parameters.dev = $val'  --arg val $DEV  <<<"$(cat env.json)" > env.json

成功了。

问题是最后一次使用 jq 给出的是原始 env.json,而不是之前使用 jq 修改的那个。我们可以通过只调用一次 jq 来解决这个问题(获得性能提升作为奖励)。

ENVJSON="$( cat env.json )"
jq \
   --arg name "$NAME" \
   --arg prod "$PROD" \
   --arg dev  "$DEV"  \
'
  .parameters.name = $name |
  .parameters.prod = $prod |
  .parameters.dev  = $dev
' <<<"$ENVJSON" >env.json

如果变量被导出,我们甚至可以使用

jq '
  .parameters.name = env.name |
  .parameters.prod = env.prod |
  .parameters.dev  = env.dev
'

顺便说一下,sponge 非常适合从同一个文件读取和写入。

jq '...' env.json | sponge env.json