Reputation: 991
I have this json file:
{
"orders": "[{\"items\":[{\"itemid\":'',\"quantity\":'',\"price\":'',\"currency\":\"IDR\",\"shopid\":'',\"item_group_id\":null,\"add_on_deal_id\":null,\"checkout\":true}],\"shopid\":''}]",
"check_voucher_payment_criteria": false,
"need_wallet_active_info": false
}
I want to replace:
itemid
with the value of 321
quantity
with the value of 1
price
with the value of 100000
shopid
with the value of 789
So the result I want is:
{
"orders": "[{\"items\":[{\"itemid\":321,\"quantity\":1,\"price\":100000,\"currency\":\"IDR\",\"shopid\":789,\"item_group_id\":null,\"add_on_deal_id\":null,\"checkout\":true}],\"shopid\":789}]",
"check_voucher_payment_criteria": false,
"need_wallet_active_info": false
}
I tried https://jqplay.org/s/x3IArefkyH:
jq --raw-output '.orders[].items = 321' file.json
But it gave me this error:
jq: error (at <stdin>:4): Cannot iterate over string ("[{\"items\...)
exit status 5
How should I fix it ?
Upvotes: 0
Views: 1745
Reputation: 116740
The complication here is that your stringified JSON isn't properly stringified. One option would be to make it valid stringified JSON, perform the updates, and stringify it again.
In the example, all the occurrences of ''
are replaced by JSON values, so it doesn't matter whether this last step (restringification) is done normally (using tojson
) or not, so in the following, only the normal stringification is performed.
.orders |= (gsub("''";"\"\"") | fromjson)
| .orders[0].items[0] |= (.itemid = 321 | .quantity=1 | .price = 100000 | .shopid = 789)
| .orders[0].shopid = 789
| .orders |= tojson
Whether that first gsub
should be as shown or
(gsub("'";"\"")
or something else will depend on the processes that produce and consume that mish-mash.
Upvotes: 1
Reputation: 13249
In order to let jq
understand the the json string inside the orders
element, you have to replace the single quote '
in your json file by backslash double quote \"
.
Then you can use jq
to replace the wanted values by transforming the json string to object and back to string:
sed 's/\x27/\\"/g' file | \
jq '.orders|=(fromjson|map(((.items[].itemid|=321)|(.items[].quantity|=1)|(.items[].price|=10000)|(.items[].shopid|=789)))|tojson)'
{
"orders": "[{\"items\":[{\"itemid\":321,\"quantity\":1,\"price\":10000, \"currency\":\"IDR\",\"shopid\":789,\"item_group_id\":null,\"add_on_deal_id\":null,\"checkout\":true}],\"shopid\":\"\"}]",
"check_voucher_payment_criteria": false,
"need_wallet_active_info": false
}
Upvotes: 1
Reputation: 111
Your assinging the orders value as string. that's the reason you won't be able to loop through. remove the double quote when your assiging the orders vlaue like below.
{
"orders": [{"items":[{"itemid":"","quantity":"","price":"","currency":"IDR","shopid":"","item_group_id":null,"add_on_deal_id":null,"checkout":true}],"shopid":""}],
"check_voucher_payment_criteria": false,
"need_wallet_active_info": false
}
Output
Upvotes: 0