在jq中,如何确保k,v仅在被检查对象中存在时创建?例如,让我们说我有一个像这样的对象:
{
"student":{
"name": "george",
"age" : "15",
"quote": "Hello I am George"
}
}
我cat text.txt | jq '{name: .student.name, quote: .student.quote}'
创建:
{
"name": "george",
"quote": "Hello I am George"
}
然而,有些条目不完整,我不想写一个空的K,V。我们说我得到了:
{
"student":{
"name": "Shirley"
}
}
使用上面的当前jq,这将创建:
{
"name": "Shirley",
"quote": " ",
}
有没有办法告诉jq只创建'quote'
密钥(如果它不存在)?或者更一般地,只有在被检查对象中存在所有密钥时才创建所有密钥。
答案 0 :(得分:1)
这是对象添加非常方便的地方,特别是因为$obj + null
产生$obj
(如果$obj
是JSON对象):
.student | {name} + if has("quote") then {quote} else null end
或等效地:
def maybe(k): if has(k) then {(k): .[k]} else null end;
.student | {name} + maybe("quote")
稍微不同的方法,具有微妙的不同语义,将是:
.student | {name} + ((select(.quote) | {quote}) // null)
当然其他变化也是可能的。
答案 1 :(得分:1)
如果您提前知道密钥是什么并且它们是直接属性,只需构建所需的密钥数组并检查对象是否包含这些密钥。
$ jq --argjson keys '["name","quote"]' '
def copy_keys($keys): . as $o
| reduce $keys[] as $k ({}; if ($o|has($k)) then .[$k] = $o[$k] else . end)
;
.student | copy_keys($keys)' text.txt
但是你提出问题的方式,“或者更一般地说,只有当它们存在于被检查的对象中时才创建所有字段,”你只需要对象中的所有键,只要它有一把钥匙。为什么不直接拿到对象?
$ jq '.student' text.txt