skip to Main Content

I have two JSON files with different schema.
The sample data in the JSON files as

File1.json

{
  "ServiceSettings": {
    "ServiceName": "my-service",
    "RedisSettings": {
      "RedisHost": "HOST-A;HOST-B" 
    }
  }
}

File2.json:

{
  "RedisHost": "HOST-A;HOST-B"
}

I have a requirement as below and the conditions are passed through the pipelines, dynamically

I set a variable preset as

host_orderA="HOST-A;HOST-B"
&
host_orderB="HOST-B;HOST-A"

  1. if the condition is A, the RedisHost should be

    "RedisHost": "HOST-A;HOST-B"
    
  2. if the condition is B, the RedisHost should be

    "RedisHost": "HOST-B;HOST-A"
    
  3. Irrespective of the order of hosts list HOST-A & HOST-B in the actual JSON files, I want to order the hosts in the JSON and print or output data into a variable or use sponge to replace in the same JSON files, based on the conditions, 1 & 2 above.

I tried a few things using sed & JQ but was unable to attain proper output. I prefer to use JQ to replace it as it’s JSON-friendly.

2

Answers


  1. It’s not a particularly clean solution, but the following works:

    condition=A # or condition=B
    jq --arg condition "$condition" '
      def maybeReorderHost:
        ( if $condition == "A" then "HOST-A" else "HOST-B" end) as $priorityPattern |
        if type != "object" then . else (
          if .RedisHost? == null then . else (
            .RedisHost |= (split(";") as $hostArr |
            [[$hostArr[] | select(index($priorityPattern) != null)],
             [$hostArr[] | select(index($priorityPattern) == null)]]
            | add | join(";") )
        ) end
      ) end;
    
      walk(maybeReorderHost)
    ' <FileA.json
    

    We’re using split(";") to split your string into an array; filtering for the array elements that do match your desired pattern; filtering for the array elements that don’t match your pattern; and then concatenating those two sublists together.

    Login or Signup to reply.
  2. If the format of .RedisHost is fixed, you can try :

    this=B
    jq --arg this $this
        '(if $this == "A" then "B" else "A" end) as $that|
         (.. | select(type == "object" and has("RedisHost"))
               .RedisHost?) = "HOST-($this);HOST-($that)"' File1.json
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search