英文:
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 '.D = ["new value"]' test.json
{
"A": "123",
"B": "456",
"C": "789",
"D": [
"new value"
]
}
If you want to modify the current value, the operator |=
might be helpful.
An alternative, equivalent program would be '. + { D: ["new value"] }'
If you really want to fix your script, here's a working version of it:
if jq -e 'has("D")' test.json >/dev/null; then
# key exists
jq --argjson addobj '{"D": "[]"}' 'your program here' test.json
else
# key doesn't exist
jq 'your other program here'
fi
But this is arguably easier in jq directly:
jq --argjson addobj '{"D": "[]"}' '
if has("D") then
# D exists
. # <- your jq program
else
# D doesn't exist
. # <- your other jq program
end
' 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 '{D: []} + .' 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 '.D |= (. // [])' test.json
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论