如何从关联数组创建 JSON

如何从关联数组创建 JSON

我正在 CentOS 7.5 上编写一个 bash 脚本,它将执行一些 MongoDB 命令。这些命令之一将设置复制服务器。根据项目的不同,服务器的数量可以不同。

我有一个关联数组,它是服务器的主机名和 IP(我使用关联数组是因为代码的其他部分需要它)。在此示例中,我有三台服务器:

  declare -A rep_hostname
  rep_hostname=( [test1]='172.1.1.1' [test2]='172.1.1.2' [test3]='172.1.1.3'  )

当拥有三台服务器时,我必须运行以下命令:

  rs.initiate( { _id : "opino-rs", members: [ { _id: 0, host: "172.1.1.1:2701" }, 
  { _id: 1, host: "172.1.1.2:2701" }, { _id: 2, host: "172.1.1.3:2701" } ]})

如果我的阵列有两个服务器,我有这个:

  rs.initiate( { _id : "opino-rs", members: [ { _id: 0, host: "172.1.1.1:2701" }, 
  { _id: 1, host: "172.1.1.2:2701" } ]})  

我需要生成这个命令然后执行它。问题是我无法生成它。我尝试了一些代码,它们甚至与我想要的不接近。
我怎样才能做到这一点?

答案1

#!/bin/bash

declare -A rep_hostname
rep_hostname=( [test1]='172.1.1.1' [test2]='172.1.1.2' [test3]='172.1.1.3' )

json=$(
        jo _id=opino-rs members="$(
                jo -a "${rep_hostname[@]/%/:2701}" |
                jq -c 'to_entries | map({ "_id": .key, "host": .value })'
        )"
)

printf 'rs.initiate(%s)\n' "$json"

测试:

$ bash script.sh
rs.initiate({"_id":"opino-rs","members":[{"_id":0,"host":"172.1.1.3:2701"},{"_id":1,"host":"172.1.1.2:2701"},{"_id":2,"host":"172.1.1.1:2701"}]})

这同时使用jojq。该jo实用程序是一个在 shell 中创建 JSON 的工具。jo将确保生成的 JSON 被正确引用和编码。该jq实用程序是一个在 shell 中解析和处理 JSON 的工具。

我用于jo根据关联数组中的 IP 地址列表创建主机名的 JSON 列表。在创建 JSON 数组之前,我:2701通过参数替换的方式添加到每个 IP 地址的末尾。

$ jo -a "${rep_hostname[@]/%/:2701}"
["172.1.1.3:2701","172.1.1.2:2701","172.1.1.1:2701"]

读取此内容并将其修改为我们要分配给最终 JSON 中的键jq的 JSON 对象列表:members

$ jo -a "${rep_hostname[@]/%/:2701}" | jq -c 'to_entries | map({ "_id": .key, "host": .value })'
[{"_id":0,"host":"172.1.1.3:2701"},{"_id":1,"host":"172.1.1.2:2701"},{"_id":2,"host":"172.1.1.1:2701"}]

这将再次用作jo构建最终 JSON 文档的输入。

rs.initiate()在脚本的末尾,生成的 JSON 文档只需使用调用插入到字符串的括号中printf

由于我不使用 MongoDB,所以我无法说出如何以最佳方式执行此结果。

也可以看看:

相关内容