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
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)