用JQ修改嵌套的JSON数组 [英] modify nested JSON array with JQ

查看:97
本文介绍了用JQ修改嵌套的JSON数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用JQ修改以下JSON输入:

I would like to use JQ to modify the following JSON input:

{
  "rows": [
    {
      "fields": [
        {
          "name": "id",
          "value": "k1"
        },
        {
          "name": "val",
          "value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
        },
        {
          "name": "Encoding",
          "value": "hex"
        }
      ]
    },
    {
      "fields": [
        {
          "name": "id",
          "value": "k2"
        },
        {
          "name": "val",
          "value": "2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d308ea329718"
        },
        {
          "name": "Encoding",
          "value": "hex"
        }
      ]
    }
  ]
}

,以便将包含.name=="id" and .value=="k1"的行的名称为"Encoding""value"字段的"hex"值修改为"oct" .

so that the "hex" value of the "value" field with name "Encoding" is modified to "oct" only for the row that contains a field with .name=="id" and .value=="k1".

我该怎么做?我可以用.value=="k1"等来select一个字段,但似乎无法找到一种方法来爬树"以随后更新"Encoding"字段.

How would I do that? I can select a field with .value=="k1" etc. but I don't seem to be able to find a way to "go up the tree" to update the "Encoding" field subsequently.

不能期望输入具有固定的字段/行顺序.

The input cannot be expected to have a fixed field/row order.

推荐答案

使用any/2会产生一个jq过滤器,该过滤器与该问题的英语描述非常匹配:

Using any/2 yields a jq filter that closely matches the description of the problem in English:

.rows |= map( if any(.fields[]; .name=="id" and .value=="k1")
              then .fields |= map(if .name == "Encoding"
                                  then .value = "oct"
                                  else .
                                  end)
              else .
              end )

使用when/2

如果我们使用如下定义的方便的通用函数,则可能会有稍微冗长一些,也许更清晰的解决方案:

Using when/2

A slightly less verbose and perhaps clearer solution is possible if we use a handy general-purpose function defined as follows:

def when(filter; action): if (filter?) // null then action else . end;

然后我们可以简单地写:

We can then write simply:

.rows[] |= when( any(.fields[]; .name=="id" and .value=="k1");
                 .fields |= map( when (.name == "Encoding";
                                       .value = "oct")))

注意事项

  • 您可能需要先检查.value =="hex",然后再将其更改为"oct".
  • 上述过滤器可能会为每个行"更改多个名称/值对.
  • Caveats

    • You might want to check whether .value == "hex" before changing it to "oct".
    • The above filters could potentially change more than one name/value pair per "row".
    • 这篇关于用JQ修改嵌套的JSON数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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