I am attempting to update certain properties of a JSON file based on a few conditions:
- The name of the attribute must contain the string "Description".
- The attribute’s
ismydata
property must betrue
. - The attribute’s
deprecatedVersion
must have an empty string for its value.
An example JSON that I am trying to update is shown here:
{
"name": "account",
"description": "Some description",
"attributes": {
"accountNameCode": {
"description": "Name of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
},
"accountNameDescription": {
"description": "Description of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
},
"anotherDescription": {
"description": "Some other thing.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
}
}
}
At the moment, I’ve got the following script that is almost what is needed, however it duplicates the JSON body with each match that is found:
(.attributes
| with_entries( select(.key|contains("Description")))
| keys[] as $k | .[$k]
| select(.ismydata==true) and select(.deprecatedVersion=="") | $k) as $matchKey
| .attributes[$matchKey].description as $description
| .attributes[$matchKey].deprecatedVersion |= "Y"
| .attributes[$matchKey].description |= "Deprecated- this has been replaced by... " + $description
This results in the following –
{
"name": "account",
"description": "Some description",
"attributes": {
"accountNameCode": {
"description": "Name of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
},
"accountNameDescription": {
"description": "Deprecated- This property has been replaced by the enumerationDataType.description field. Description of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": "Y"
},
"anotherDescription": {
"description": "Some other thing.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
}
}
}
{
"name": "account",
"description": "Some description",
"attributes": {
"accountNameCode": {
"description": "Name of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
},
"accountNameDescription": {
"description": "Description of the account type.",
"type": "string",
"ismydata": true,
"deprecatedVersion": ""
},
"anotherDescription": {
"description": "Deprecated- This property has been replaced by the enumerationDataType.description field. Some other thing.",
"type": "string",
"ismydata": true,
"deprecatedVersion": "Y"
}
}
}
- which shows a copy of the whole structure for each match of my conditions. How do I condense this into a single output?
2
Answers
Based on the problem description and sample code, it appears you are basically trying to update .attributes; the simplest approach would probably be to use the form:
.attributes |= ...
In fact, the following appears to be a solution:
(This solution is quite similar to the one suggested by @Newpaw but subsequently deleted.)
Your solution can be salvaged by using
reduce
over $matchKey: