Json 如何使用jq有条件地更改所有记录上的多个值

Json 如何使用jq有条件地更改所有记录上的多个值,json,jq,Json,Jq,我设法得到了我所需要的,但我想我可能不需要给jq打多次电话就可以做到。你知道我怎么能只打一个jq电话就做到这一点吗 |jq -r --arg replace 'Cancelled' '.result|= map(if .is_cancelled == true then (.is_cancelled=$replace) else . end)' \ |jq -r --arg replace 'Started' '.result|= map(if .is_started == true then

我设法得到了我所需要的,但我想我可能不需要给jq打多次电话就可以做到。你知道我怎么能只打一个jq电话就做到这一点吗

|jq -r --arg replace 'Cancelled' '.result|= map(if .is_cancelled == true then (.is_cancelled=$replace) else . end)' \
|jq -r --arg replace 'Started' '.result|= map(if .is_started == true then (.is_started=$replace) else . end)' \
|jq -r --arg replace 'Stopped' '.result|= map(if .is_started == false then (.is_started=$replace) else . end)' \
|jq -r --arg replace 'Active' '.result|= map(if .is_cancelled == false then (.is_cancelled=$replace) else . end)' 
传递给jq的数据如下所示:

{
  "result": [
    {
      "id": 8893,
      "entry_time": "2020-11-04T16:02:43+01:00",
      "author_id": 24,
      "author_name": "joe",
      "host_id": 2115,
      "service_id": 0,
      "is_cancelled": false,
      "comment": "Test 5236",
      "deletion_time": null,
      "duration": 4302000,
      "end_time": "2020-12-24T13:48:22+01:00",
      "internal_id": 513,
      "is_fixed": true,
      "poller_id": 2,
      "start_time": "2020-11-04T18:48:22+01:00",
      "actual_start_time": "2020-11-18T12:08:16+01:00",
      "actual_end_time": null,
      "is_started": true
    },
    {
      "id": 8894,
      "entry_time": "2020-11-04T16:02:43+01:00",
      "author_id": 24,
      "author_name": "joe",
      "host_id": 2115,
[…]
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "limit": 999999999,
      "search": {},
      "sort_by": {
        "host.name": "DESC"
      },
      "total": 118
    }
  }
}
结果是这样的:

{
  "result": [
    {
      "id": 8893,
      "entry_time": "2020-11-04T16:02:43+01:00",
      "author_id": 24,
      "author_name": "joe",
      "host_id": 2115,
      "service_id": 0,
      "is_cancelled": "Active",
      "comment": "Test 5236",
      "deletion_time": null,
      "duration": 4302000,
      "end_time": "2020-12-24T13:48:22+01:00",
      "internal_id": 513,
      "is_fixed": true,
      "poller_id": 2,
      "start_time": "2020-11-04T18:48:22+01:00",
      "actual_start_time": "2020-11-18T12:08:16+01:00",
      "actual_end_time": null,
      "is_started": "Started"
    },
[…]
在.result的所有记录上,字段“is_started”和“is_cancelled”的假值和真值将替换为一些其他值


只调用一次jq是否可以进行相同的更改?

您可以简单地重命名“-arg”变量:

jq -r --arg cancel Cancelled \
      --arg start Started    \
      --arg stop Stopped     \
      --arg replace Active '
.result|= map(if .is_cancelled == true then (.is_cancelled=$cancel) else . end)
| .result|= map(if .is_started == true then (.is_started=$start) else . end)
| .result|= map(if .is_started == false then (.is_started=$stop) else . end)
| .result|= map(if .is_cancelled == false then (.is_cancelled=$replace) else . end)
' 
下一步是对其进行重新表述,以避免在数组中重复迭代,因此jq过滤器可能如下所示:

  .result |= 
     map(if .is_cancelled == true then (.is_cancelled=$cancel) 
         elif .is_cancelled == false then (.is_cancelled=$replace) 
         else . 
         end
         | if .is_started == true then (.is_started=$start) 
           elif .is_started == false then (.is_started=$stop) 
           else .
           end )

潜在简化 <>你也可以考虑下面的内容,但这可能过于简单化:

  .result |= 
     map(.is_cancelled |= if . then $cancel else $replace end
         | .is_started |= if . then $start else $stop end)
传递参数的另一种方法 有几种不那么繁琐的方法来传递这四个参数;你可能想考虑这种可能性,例如:

jq -r --argjson v '
    {"cancel": "Cancelled", "start": "Started", "stop": "Stopped",  "replace": "Active"}' '
  .result |= 
     map(.is_cancelled |= if . then $v.cancel else $v.replace end
         | .is_started |= if . then $v.start else $v.stop end)
'

你是对的,我错过了OP中关于
其他的部分。
que@Inian-您必须编写
。is|u cancelled |=(选择()|$v.cancel//$v.replace)
,我认为这比如果…那么…否则…结束更难理解