skip to Main Content

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 be true.
  • 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


  1. 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:

    .attributes |=
      with_entries(
        if (.key|contains("Description")) 
            and .value.ismydata == true
            and .value.deprecatedVersion == ""
        then .value |= 
          ((.deprecatedVersion = "Y")
           | .description |= "Deprecated- this has been replaced by... (.)")
        else .
        end)
    

    (This solution is quite similar to the one suggested by @Newpaw but subsequently deleted.)

    Login or Signup to reply.
  2. Your solution can be salvaged by using reduce over $matchKey:

      reduce (
         .attributes
         | ( with_entries( select(.key|contains("Description"))) 
             | keys[] as $k | .[$k] 
             | select(.ismydata==true) and select(.deprecatedVersion=="") | $k)) as $matchKey (.;
           .attributes[$matchKey].deprecatedVersion = "Y"
         | .attributes[$matchKey].description |= "Deprecated- this has been replaced by... (.)" )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search