Reputation: 506
I managed to get what I needed, but I think I could possibly do it without having to call jq multiple times. Do you know how I can do the same with only one jq call ?
|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)'
The data passed to jq looks like this :
{
"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
}
}
}
The result is something like that :
{
"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"
},
[…]
false and true values are replaced with some other values for the fields "is_started" and "is_cancelled", on all records of .result.
Is it possible to do the same change with calling jq only once ?
Upvotes: 1
Views: 173
Reputation: 116740
You could begin by simply renaming the "--arg" variables:
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)
'
The next step would be to rephrase this to avoid the repeated iterations through the array, so that the jq filter might look like this:
.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 )
You might also wish to consider the following, which however might be an oversimplification:
.result |=
map(.is_cancelled |= if . then $cancel else $replace end
| .is_started |= if . then $start else $stop end)
There are several less tedious ways to pass in the four parameters; you might like to consider this possibility, for example:
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)
'
Upvotes: 2