基于标志的值对JSON嵌入的字符串中的值重新排序

a1o7rhls  于 2023-10-21  发布在  其他
关注(0)|答案(3)|浏览(121)

我有两个不同模式的JSON文件。JSON文件中的示例数据为
File1.json

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

File2.json:

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

我有一个如下的需求,条件通过管道动态传递
我设置一个变量预置为
host_orderA="HOST-A;HOST-B" & host_orderB="HOST-B;HOST-A"
1.如果条件是A,则RedisHost应该是

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

1.如果条件为B,则RedisHost应为

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

1.不管主机列表HOST-A和HOST-B在实际JSON文件中的顺序如何,我想在JSON中对主机进行排序,并将数据打印或输出到变量中,或者根据上面的条件1和2使用sponge在相同的JSON文件中进行替换。
我尝试了一些使用sed & JQ的东西,但无法获得正确的输出。我更喜欢使用JQ来代替它,因为它是JSON友好的。

7ajki6be

7ajki6be1#

这不是一个特别 * 干净 * 的解决方案,但以下工作:

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

我们使用split(";")将字符串拆分为数组;过滤与你想要的模式匹配的数组元素;过滤与你的模式不匹配的数组元素;然后将这两个子列表连接在一起。

wqnecbli

wqnecbli2#

如果.RedisHost的格式是固定的,你可以尝试:

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
uqcuzwp8

uqcuzwp83#

我自己解决的。

# To detect the condition at the pipeline level based on the environment 

    detect=< To detect the condition to apply > # more at Pipeline

   # Defining list of host variables

    host_A=HOST-A; host_B=HOST-B

   # construct host order based on $detect 
 
    if [[ $detect =~ A ]]; then order_host="$host_A;$host_B"; elif
       [[ $detect =~ B ]] ; then 
       order_host="$host_B;$host_A" ; else 
       echo "Invalid ";
    fi

   # find the RedisHost and replace it with the constructed order_host

    jq --arg myvar "$order_host" '(..|objects|select(.RedisHost).RedisHost)|=$myvar' File1.json)"
    jq --arg myvar "$order_host" '(..|objects|select(.RedisHost).RedisHost)|=$myvar' File2.json)"

相关问题