Yelena
Yelena

Reputation: 11

jq: how to change array value conditionally

A am new at json and jq. I searched internet but could not find solution for my problem. I have a json file with each object containing array. I need to change some of array elements conditionally: if contact_type = email and value like "yahoo.com" replace "yahoo.com" with "hotmail.com". My file:

[  
    {
        "name": "fluffy",
        "type": "cat",
        "contact_info": [
             {
                 "contact_type": "phone",
                 "value": "123-456-6789"
             },
             {
                 "contact_type": "email",
                 "value": "[email protected]"
             }
        ]
    },
    {
         "name": "breeze",
         "type": "dog",
         "contact_info": [
             {
                  "contact_type": "phone",
                  "value": "125-856-6789"
             },
             {
                  "contact_type": "email",
                  "value": "[email protected]"
             }
         ]
    }
]

Resulting file has to look like this:

[
    {
         "name": "fluffy",
         "type": "cat",
         "contact_info": [
             {
                  "contact_type": "phone",
                  "value": "123-456-6789"
             },
             {
                  "contact_type": "email",
                  "value": "[email protected]"
             }
         ]
    },
    {
         "name": "breeze",
         "type": "dog",
         "contact_info": [
             {
                  "contact_type": "phone",
                  "value": "125-856-6789"
             },
             {
                  "contact_type": "email",
                  "value": "[email protected]"
             }
         ]
    }
]

Please help.

Upvotes: 1

Views: 349

Answers (1)

peak
peak

Reputation: 116740

Here's one of many possible solutions:

walk( if type == "object"
        and .contact_type == "email"
        and (.value | index("yahoo.com"))
      then .value |= sub("yahoo.com"; "hotmail.com")
      else . end )

Direct approach

def update:
  if .contact_type == "email"
     and (.value | index("yahoo.com"))
  then .value |= sub("yahoo.com"; "hotmail.com")
  else . 
  end ;

map( if .contact_info 
     then .contact_info |= map(update)
     else .
     end )

else .

After the release of jq 1.6, a change was made allowing the else . to be dropped.

Upvotes: 1

Related Questions