jq 1.5匹配2个或更多键匹配名称和值的记录 [英] jq 1.5 match a record where 2 or more keys match names and values

查看:49
本文介绍了jq 1.5匹配2个或更多键匹配名称和值的记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不太确定如何清楚地提出问题,但是考虑到如下所示的递归结构.如何使用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可能会同时匹配idother.

I would like to find a record where key=id=ddd && key=parent=cccI 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆