如何使用jq在json文件中创建键?

huangapple go评论62阅读模式
英文:

How to create keys in json file using jq?

问题

{
	"A": "123",
	"B": "456",
	"C": "789",
}
英文:

I am trying to update a json file using jq. My json file looks like

{
	"A": "123",
	"B": "456",
	"C": "789",
	"D": []
}

Here the value for key D is empty so I am adding some values to it. And this is working

Now, if for some reason the key doesn't exist then I need to first create the key D. And I am not able to achieve this

{
	"A": "123",
	"B": "456",
	"C": "789",
}
cat test.json | jq 'has("D")' = false && cat test.json jq --argjson addobj '{"D": "[]"}'

I am getting the error

jq: error: Could not open file =: No such file or directory
jq: error: Could not open file false: No such file or directory

expected output

{
	"A": "123",
	"B": "456",
	"C": "789",
	"D": []
}

Can anyone please let me know what is the issue here and how to resolve it?

Thanks in advance.

P.S: Please let me know if any info is missing here

答案1

得分: 2

您的问题不仅涉及jq,还涉及shell语法。

但是,如果您只是想更新键D的值,无论它是否存在,那么您不需要任何检查,可以简单地分配新值:

$ jq '.D = ["new value"]' test.json 
{
  "A": "123",
  "B": "456",
  "C": "789",
  "D": [
    "new value"
  ]
}

如果您想修改当前值,|= 运算符可能会有所帮助。

一个等效的替代程序可能是 '. + { D: ["new value"] }'


如果您真的想修复您的脚本,这里是一个有效的版本:

if jq -e 'has("D")' test.json >/dev/null; then
  # 键存在
  jq --argjson addobj '{"D": "[]"}' '这里是您的程序' test.json
else
  # 键不存在
  jq '这里是您的其他程序'
fi

但这在jq中直接处理可能更容易:

jq --argjson addobj '{"D": "[]"}' '
if has("D") then
  # D存在
  . # <- 您的jq程序
else
  # D不存在
  . # <- 您的其他jq程序
end
' test.json

如果您的目标只是在键不存在时插入具有默认值的键,但保留任何现有值,那么以下简单的jq程序(和其他任何内容)应该处理这个问题:

jq '{D: []} + .' test.json

(RHS中的键会覆盖LHS中的键 – {a:1}+{a:2} 变成 {a:2}

JavaScript(以及JSON)中的对象是一个无序的键-值对集合,{a:1,b:2}{b:2,a:1} 是相同的对象。

然而,jq大部分保留键的顺序(尽管我认为这并没有被规定/保证)。因此,稍微复杂一点的版本会将 D 放在对象的末尾,但保留现有的值:

jq '.D |= (. // [])' test.json
英文:

Your problem is not (only) with jq, but with shell syntax.

But if all you are trying to do is to update the value of key D whether it exists or not, then you don't need any checks and can simply assign the new value:

$ jq &#39;.D = [&quot;new value&quot;]&#39; test.json 
{
  &quot;A&quot;: &quot;123&quot;,
  &quot;B&quot;: &quot;456&quot;,
  &quot;C&quot;: &quot;789&quot;,
  &quot;D&quot;: [
    &quot;new value&quot;
  ]
}

If you want to modify the current value, the operator |= might be helpful.

An alternative, equivalent program would be &#39;. + { D: [&quot;new value&quot;] }&#39;


If you really want to fix your script, here's a working version of it:

if jq -e &#39;has(&quot;D&quot;)&#39; test.json &gt;/dev/null; then
  # key exists
  jq --argjson addobj &#39;{&quot;D&quot;: &quot;[]&quot;}&#39; &#39;your program here&#39; test.json
else
  # key doesn&#39;t exist
  jq &#39;your other program here&#39;
fi

But this is arguably easier in jq directly:

jq --argjson addobj &#39;{&quot;D&quot;: &quot;[]&quot;}&#39; &#39;
if has(&quot;D&quot;) then
  # D exists
  . # &lt;- your jq program
else
  # D doesn&#39;t exist
  . # &lt;- your other jq program
end
&#39; test.json

If your goal is to simply insert the key with a default value if it doesn't exist, but keep any existing value, the following simple jq program (and nothing else) should take care of that:

jq &#39;{D: []} + .&#39; test.json

(keys in the RHS overwrite keys from the LHS – {a:1}+{a:2} becomes {a:2})

Objects in JavaScript (and by extension JSON), are a bag of unordered key-value pairs and {a:1,b:2} is the same object as {b:2,a:1}.

However, jq mostly keeps order of keys (although I don't think this is specified/guaranteed). So, a slightly more complicated version which puts D at the end of the object, but keeps existing values would be:

jq &#39;.D |= (. // [])&#39; test.json

huangapple
  • 本文由 发表于 2023年2月8日 15:03:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75382353.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定