Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to replace multiple values in json file using jq and returning the whole content

I have a json like this

[{"version": 0.0,"Resources": [ {"TargetService": {"Type": "AWS::ECS::Service","Properties": {"TaskDefinition": "abc","LoadBalancerInfo": {"ContainerName": "def","ContainerPort": 8080}}}} ]}]

My attempt is to replace TaskDefinition key value from "abc" to "123" and ContainerName key value from "def" to "456 in one command and return the whole update json.

This is what i tried

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

echo $APP_SPEC | jq --arg TASK_DEFINITION "123" '(.[].Resources[].TargetService | select(.Properties)).TaskDefinition |=$TASK_DEFINITION')

But the substistuion is not happening properly and the value gets appended at the end of the josn as below.

Incorrect response:

[ { "version": 0, "Resources": [ { "TargetService": { "Type": "AWS::ECS::Service", "Properties": { "TaskDefinition": "abc", "LoadBalancerInfo": { "ContainerName": "container_name", "ContainerPort": 8080 } }, "TaskDefinition": "123" } } ] } ] 

>Solution :

Use the update operator |=

.[].Resources[].TargetService.Properties |= (
  .TaskDefinition = "123"
  | .LoadBalancerInfo.ContainerName = "456"
)

Demo


Note that select only filters its input, it does not descend into the filter criterion. So, if you only want to make the update if the .Properties field exists, use select and descend into it.

( .[].Resources[].TargetService
  | select(.Properties).Properties
) |= (
  .TaskDefinition = "123"
  | .LoadBalancerInfo.ContainerName = "456"
)

Demo


Note that the filter select(.Properties) will produce false if the content of that field, albeit existing, evaluates to null or false. If you want to consider such cases also as "existent", use has in the select filter to test for it.

( .[].Resources[].TargetService
  | select(has("Properties")).Properties
) |= (
  .TaskDefinition = "123"
  | .LoadBalancerInfo.ContainerName = "456"
)

Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading