I have the given JSON and want to change the id
value of all elements, which starts with test
in the name
element:
{
"other-value": "some-id",
"values": [
{
"name": "test-2017-12-01",
"id": "1"
},
{
"name": "othert",
"id": "2"
}
]
}
The following jq commands works jqplay
jq (.values[] | select(.name == "test-afs").id) |= "NEWID"
But when I try it with startswith
it stops working, what am I missing? jqplay
(.values[] | select(.name | startswith("test")).id) |= "NEWID"
jq: error (at :14): Invalid path expression near attempt to access element "id" of {"name":"test-afs","id":"id"} exit status 5
jq is an amazing little command line utility for working with JSON data. We've written before about how you can use jq to parse JSON on the command line, but in this post I want to talk about using jq to create JSON data from scratch or make changes to existing data.
jq filters run on a stream of JSON data. The input to jq is parsed as a sequence of whitespace-separated JSON values which are passed through the provided filter one at a time. The output(s) of the filter are written to standard out, again as a sequence of whitespace-separated JSON data.
jq is a program described as “ 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.
So, to implement bash shell scripts using REST APIs, you must know how to parse the response of REST API (that is, parse JSON data). Jq is a program developed to filter JSON data. You can consider Jq like sed, awk, or grep program but designed specifically for filtering JSON data.
You can also use map
, like this:
jq '(.values)|=(map((if .name|startswith("test") then .id="NEWID" else . end)))' file
Output:
{
"other-value": "some-id",
"values": [
{
"name": "test-2017-12-01",
"id": "NEWID"
},
{
"name": "othert",
"id": "2"
}
]
}
Please note that since the release of jq 1.5, jq has been enhanced to support the query that previously failed. For example, using the current 'master' version:
jq -c '(.values[] | select(.name | startswith("test")).id) |= "NEWID"'
{"other-value":"some-id","values":[{"name":"test-2017-12-01","id":"NEWID"},{"name":"othert","id":"2"}]}
Using earlier versions of jq, if/then/else/end can be used in this type of situation as follows:
.values[] |= if .name | startswith("test") then .id = "NEWID" else . end
If using map
, a minimalist expression would be:
.values |= map(if .name|startswith("test") then .id = "NEWID" else . end)
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