Appologies if I've overlooked something very obvious; I've just found jq
and am trying to use it to update one JSON value without affecting the surrounding data.
I'd like to pipe a curl
result into jq
, update a value, and pipe the updated JSON to a curl -X PUT
. Something like
curl http://example.com/shipping.json | jq '.' field: value | curl -X PUT http://example.com/shipping.json
So far I've hacked it together using sed
, but after looking at a few examples of the |=
operator in jq
I'm sure that I don't need these.
Here's a JSON sample--how would I use jq
to set "local": false
, while preserving the rest of the JSON?
{
"shipping": {
"local": true,
"us": true,
"us_rate": {
"amount": "0.00",
"currency": "USD",
"symbol": "$"
}
}
}
jq is equally useful for updating existing JSON data.
jq is a lightweight and flexible command-line JSON processor. If you are a command line addict, you will like the official description. jq is like sed for JSON data – you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text.
You set values of an object using the =
operator. |=
on the other hand is used to update a value. It's a subtle but important difference. The context of the filters changes.
Since you are setting a property to a constant value, use the =
operator.
.shipping.local = false
Just note that when setting a value to a property, it doesn't necessarily have to exist. You can add new values easily this way.
.shipping.local = false | .shipping.canada = false | .shipping.mexico = true
Update a value (sets .foo.bar to "new value"):
jq '.foo.bar = "new value"' file.json
Update a value using a variable (sets .foo.bar to "hello"):
variable="hello"; jq --arg variable "$variable" '.foo.bar = $variable' file.json
a similar function to the operator |= is map. map will be suitable to avoid the requirement of a previous filter for the array...
imagine that your data is an array (very common for this example)
[
{
"shipping": {
"local": true,
"us": true,
"us_rate": {
"amount": "1.00",
"currency": "USD",
"symbol": "$"
}
}
},
{
"shipping": {
"local": true,
"us": true,
"us_rate": {
"amount": "1.00",
"currency": "USD",
"symbol": "$"
}
}
}
]
hence it is necessary to consider the array in the code as:
http://example.com/shipping.json | jq '.[] | .shipping.local = "new place"' | curl -X PUT http://example.com/shipping.json
or to use the map function that is crafted to work in every array element as
http://example.com/shipping.json | jq 'map(.shipping.local = "new place")' | curl -X PUT http://example.com/shipping.json
Observation
For the sake of those that are learning, you also did some mistakes in the jq usage, just consider that it does "read" the 1st parameter as the program, hence all the desired commands shall be included in the very first string after calling the program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With