jq 1.5匹配2个或更多键匹配名称和值的记录 [英] jq 1.5 match a record where 2 or more keys match names and values
问题描述
不太确定如何清楚地提出问题,但是考虑到如下所示的递归结构.如何使用walk
将2个或更多键字符串与值匹配.我不知道结果在结构中的什么位置.它可能是顶层,也可能是十层.
Not quite sure how to ask the question clearly but, given a recursive structure as below. How would I use walk
to match 2 or more key strings to values. I will not know where in the structure the result will be. It could be the top level or 10 levels deep.
"children": {
"ccc": [{
"id": "ddd",
"des": "object d",
"parent": "ccc",
"other": "zzz"
},{
"id": "zzz",
"des": "object z",
"parent": "ccc",
"other" : "ddd"
}]
}
我想找到一个记录,其中key=id=ddd
&& key=parent=ccc
然后,我想向该记录添加新的键/值.使用.key|match("")
将使我与键的值匹配,但不能匹配键名本身.因此,搜索ddd
可能会同时匹配id
和other
.
I would like to find a record where key=id=ddd
&& key=parent=ccc
I would then like to add a new key/value to that record. Using .key|match("")
will give me a match to the value of the key but not the key name itself. So searching for ddd
may match both id
and other
.
我尝试了一些连击,如果在bash中进行操作,它将看起来像
I have tried several combos and if doing in bash it would look something like
match_criteria
match_criteria
((.key|match("id") and (.key|test("ddd"))
and
((.key|match("parent") and (.key|test("ccc"))
new_key_value
new_key_value
+= {"newkey":"newValue"}
将匹配语句插入
walk(if type == "object"
then
with_entries(if ..match_criteria.. )
then ..new_key_value.. else . end)
所以结果应该看起来像
"children": {
"ccc": [{
"id": "ddd",
"des": "object d",
"parent": "ccc",
"other": "zzz",
"newkey": "newValue"
},{
"id": "zzz",
"des": "object z",
"parent": "ccc",
"other":"ddd"
}]
}
更新 根据@peak回答中的反馈,我将代码更新如下
UPDATE based on feedback in the answer from @peak i have updated the code as follows
jsonOut=$(jq 'walk(when(type == "object";
with_entries(
when(any(.value[]; .id == "ddd");
.value[] += {"newkey": "newValue"}
))))' <<< ${jsonIn})
不幸的是,这仍然留下了两个未解决的问题
unfortunately this still leaves two open issues
a)此代码将{"newkey": "newValue"}
添加到所有符合搜索条件的子级,即:同时添加到id:ddd
&& id:zzz
,而不仅仅是id:ddd
记录
a) this code adds {"newkey": "newValue"}
to all children where the search criteria is true, ie: to both id:ddd
&& id:zzz
, rather than to just the id:ddd
record
"children": {
"ccc": [{
"id": "ddd",
"des": "object d",
"parent": "ccc",
"other": "zzz",
"newkey": "newValue"
},{
"id": "zzz",
"des": "object z",
"parent": "ccc",
"other":"ddd",
"newkey": "newValue"
}]
}
b)在any
子句中添加多个节条件.我尝试使用AND
或|
联接方法,但这会引发错误.
b) adding multiple section criteria to the any
clause. I have tried using the AND
or |
joining methods but this throws errors.
when(any(.value[]; .id == "ddd" | .other == "zzz"); //no match, no value added
or
when((any(.value[]; .id == "ddd") AND (any(.value[]; .other == "zzz"));
//error : unexpected ')', expecting $end
or
when(any(.value[]; .id == "ddd", .other == "zzz"); //no match, no value added
您能为这两个问题提供语法建议吗?
Can you advise the syntax for both issues.
UPDATE2 更好地了解了when
过滤器,我现在将它们嵌套了,这似乎可以缩小结果集.但是,在匹配为true时更新两个记录的问题a)
仍然存在.
UPDATE2 Understanding the when
filter a littler better, I have now nested these and it seems to work in narrowing the result set. However problem a)
updating both records when a match is true still exists.
jsonOut=$(jq 'walk(when(type == "object";
with_entries(
when(any(.value[]; .id == "ddd");
when(any(.value[]; .other == "zzz");
.value[] += {"newkey": "newValue"}
)))))' <<< ${jsonIn})
jsonIn
{"children": {
"ccc": [{
"id": "ddd",
"des": "object d",
"parent": "ccc",
"other": "zzz"
},{
"id": "zzz",
"des": "object z",
"parent": "ccc",
"other":"ddd"
}],
"www": [{
"id": "ddd",
"des": "object d",
"parent": "www",
"other": "ppp"
},{
"id": "kkk",
"des": "object z",
"parent": "www",
"other":"ddd"
}]
}}
jsonOut
{
"children": {
"ccc": [{
"id": "ddd",
"des": "object d",
"parent": "ccc",
"other": "zzz",
"newkey": "newValue"
}, {
"id": "zzz",
"des": "object z",
"parent": "ccc",
"other": "ddd",
"newkey": "newValue" <=need to NOT add this entry
}],
"www": [{
"id": "ddd",
"des": "object d",
"parent": "www",
"other": "ppp"
}, {
"id": "kkk",
"des": "object z",
"parent": "www",
"other": "ddd"
}]
}
}
推荐答案
以下是对"UPDATED"问题的答复:
Here is a response to the "UPDATED" question:
walk(when(type == "object";
with_entries(when(.key|test("ccc");
.value |= map( when(.id=="ddd";
. + {"newkey": "newValue"}))))))
ps.
将来,请遵循mcve准则: http://stackoverflow.com/help/mcve
这篇关于jq 1.5匹配2个或更多键匹配名称和值的记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!