如何使用JQ更新JSON并获取更新的值

时间:2017-04-01 15:45:01

标签: json updates increment jq

我在JSON中有一些数据,我想用JQ编辑。

  • 这是一个人名单。
  • 每个人都可以拥有一个或多个mobile
  • 每个mobile都有number(显然是唯一的)而不是。 calls制作的。
  • 此人也会跟踪total来电(他们拥有的每部手机的来电总数)

我试图在这里使用自解释变量。如果数据不够清楚,请告诉我。

[
  {
    "name": "Person1",
    "mobiles": [{
      "number": "11111",
      "calls": 2
    },{
      "number": "22222",
      "calls": 3
    }],
    "total": 5
  },
  {
    "name": "Person2",
    "mobiles": [{
      "number": "33333",
      "calls": 1
    },{
      "number": "44444",
      "calls": 2
    },{
      "number": "55555",
      "calls": 1
    }],
    "total": 4
  }
]

我想要的是,给定一个手机号码而不是。在特定日期对该移动电话进行的呼叫,更新json(更新个人计数器和总计)

EG。让我们说数字444444调用是5,那么最后的json应该是

[
  {
    "name": "Person1",
    "mobiles": [{
      "number": "11111",
      "calls": 2
    },{
      "number": "22222",
      "calls": 3
    }],
    "total": 5
  },
  {
    "name": "Person2",
    "mobiles": [{
      "number": "33333",
      "calls": 1
    },{
      "number": "44444",
      "calls": 7 // previous value was 2, added 5 more
    },{
      "number": "55555",
      "calls": 1
    }],
    "total": 9 // previous total was 4, added 5 more
  }
]

到目前为止我尝试了什么

我可以更新total来电,但不能更新给定号码的个别来电

map(select(.mobiles[].number == "44444").total = .total + 5)给出了

[
  {
    "name": "Person1",
    "mobiles": [
      {
        "number": "11111",
        "calls": 2
      },
      {
        "number": "22222",
        "calls": 3
      }
    ],
    "total": 5
  },
  {
    "name": "Person2",
    "mobiles": [
      {
        "number": "33333",
        "calls": 1
      },
      {
        "number": "44444",
        "calls": 2 // How do I update this
      },
      {
        "number": "55555",
        "calls": 1
      }
    ],
    "total": 9 // This is correct
  }
]

1 个答案:

答案 0 :(得分:2)

要更新您正在探索的相关“来电”:

map( (.mobiles[] | select(.number == $number) | .calls) += $incr)

其中$ number和$ incr的值可以(例如)在命令行中指定,例如

jq --arg number 44444 --argjson incr 5 -f update.jq input.json

要更新相关的“总计”,您可以使用any/2

map( if any(.mobiles[]; .number == $number) 
     then .total += $incr
     else . 
     end)

您可以通过将两个过滤器组合成一个map来将这两个链接在一起,或者字面上,或者(可能更有效)。为了便于阅读和维护,您可能还需要定义辅助函数(即使用def)。