【问题标题】:jq: adding nested object to a JSONjq:将嵌套对象添加到 JSON
【发布时间】:2016-06-19 07:09:19
【问题描述】:

我有一个包含多个配置文件的 json 文件:

{
  "profile1": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook1"
  },
  "default": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook2"
  }
}

我想用 jq 插入另一个配置文件“test”,这样最终的结果就是

{
  "profile1": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook1"
  },
  "default": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook2"
  },
  "test": {
    "user": "user3",
    "channel": "channel3",
    "hook": "hook3"
  }
}

直接在命令行中我可以这样做:

cat filename | 
    jq  '.+  { "test": { "user": "u3", "channel" : "c3", "hook": "w3" } }'

但是当我在我的 bash 脚本中尝试时:

cat "$CONF_FILE" | 
    jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
    '.+ { $p: { "user": $u, "channel": $c, "hook": $w } }' `

我收到以下错误:

jq: error: syntax error, unexpected ':', expecting '}' (Unix shell quoting issues?) at <top-level>, line 1:
.+ { $p: { "user": $u, "channel": $c, "hook": $w } }
jq: error: syntax error, unexpected '}', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
.+ { $p: { "user": $u, "channel": $c, "hook": $w } }
jq: 2 compile errors

我尝试用引号将变量括起来,但我得到的只是字符串 $p:

cat "$CONF_FILE" | 
    jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
    '.+ { "$p": { "user": $u, "channel": $c, "hook": $w } }' 

结果:

{
  "profile1": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook1"
  },
  "default": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook2"
  },
  "$p": {
    "user": "user3",
    "channel": "channel3",
    "hook": "hook3"
  }
}



编辑:我找到了一个临时解决方案,将对象转换为数组,编辑值(现在配置文件名称是值而不是键)并将数组转换回一个对象:

cat "$CONF_FILE" | 
    jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
    'to_entries | .+ [ { "key": $p, "value": { "user": $u, "channel": $c, "hook": $w } } ] | from_entries'

它看起来很粗糙,但它确实有效。我仍然希望有更好的解决方案...

【问题讨论】:

  • 看起来您要插入的 shell 变量之一是空的
  • 你能详细说明一下吗?当我使用相同的变量作为值而不是键时,它可以工作。
  • 我的意思是这个变量:--arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH"。你确定它们都设置好了而不是空的吗?
  • 嗯。很难说。顺便说一句,cat file | jq ... 是对 cat 的无用使用。应该是jq ... file
  • 如果您尝试jq --arg foo bar '{$foo}' &lt;&lt;&lt; '1'(jq>=1.5),您会看到$foo 在作为键引用时扩展为{"foo":"bar"}。我猜您看到的错误与 that 有关。用正确的话很难说。看看别人怎么说

标签: json bash jq


【解决方案1】:

这是一个脚本,演示了使用env 访问通过环境传递的变量的解决方案:

#!/bin/bash

CONF_FILE=data.json

export P=test
export U=user3
export C=channel3
export W=hook3

jq '
    .[env.P] = {
       user:    env.U, 
       channel: env.C, 
       hook:    env.W
    }
' "$CONF_FILE"

如果data.json 包含此脚本应生成输出的示例数据

{
  "profile1": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook1"
  },
  "default": {
    "user": "user1",
    "channel": "channel1",
    "hook": "hook2"
  },
  "test": {
    "user": "user3",
    "channel": "channel3",
    "hook": "hook3"
  }
}

【讨论】:

    【解决方案2】:

    在动态键周围使用括号:

    jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
    '. + {($p): {"user": $u, "channel": $c, "hook": $w}}' "$CONF_FILE"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多