在 shell 脚本中生成 JSON

Mar*_*ara 5 shell-script json

我需要生成 JSON 输出,如下所示:

[{
    "Service": "service1-name",
    "AWS Account": "service1-dev",
    "AD Accounts": {
        "APP-Service1-Admin": ["a", "b"],
        "APP-Service1-View": ["c", "d"]
    }
}
]
Run Code Online (Sandbox Code Playgroud)

我正在尝试这个 shell 脚本,但无法插入内部信息

#!/bin/bash
innerAD=$(jq -n --arg aaaa aaaa \
              --arg xxxx "xxxx" \
              '$ARGS.named'
)
inner=$(jq -n --argjson "APP-Service1-Admin" "[$innerAD]" \
              '$ARGS.named'
)
final=$(jq -n --arg Service "service1-name" \
              --arg "AWS Account" "service1-dev" \
              --argjson "AD Accounts" "[$inner]" \
              '$ARGS.named'
)
echo "$final"
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 5

一种建议是使用--argswithjq创建两个数组,然后将它们收集到主文档中的正确位置。请注意,--args必须是命令行上的最后一个选项,并且所有剩余的命令行参数都将成为$ARGS.positional数组的元素。

{
    jq -n --arg key APP-Service1-Admin '{($key): $ARGS.positional}' --args a b
    jq -n --arg key APP-Service1-View  '{($key): $ARGS.positional}' --args c d
} |
jq -s --arg key 'AD Accounts' '{($key): add}' |
jq --arg Service service1-name --arg 'AWS account' service1-dev '$ARGS.named + .'
Run Code Online (Sandbox Code Playgroud)

前两次jq调用创建一组两个 JSON 对象:

{
  "APP-Service1-Admin": [
    "a",
    "b"
  ]
}
{
  "APP-Service1-View": [
    "c",
    "d"
  ]
}
Run Code Online (Sandbox Code Playgroud)

第三次jq调用用于-s将该集合读入数组,该数组在传递时成为合并对象add。合并的对象被分配给我们的顶级键:

{
  "AD Accounts": {
    "APP-Service1-Admin": [
      "a",
      "b"
    ],
    "APP-Service1-View": [
      "c",
      "d"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

最后jq将剩余的顶级键及其值添加到对象中:

{
  "Service": "service1-name",
  "AWS account": "service1-dev",
  "AD Accounts": {
    "APP-Service1-Admin": [
      "a",
      "b"
    ],
    "APP-Service1-View": [
      "c",
      "d"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

jo

jo -d . \
    Service=service1-name \
    'AWS account'=service1-dev  \
    'AD Accounts.APP-Service1-Admin'="$(jo -a a b)" \
    'AD Accounts.APP-Service1-View'="$(jo -a c d)"
Run Code Online (Sandbox Code Playgroud)

“内部”对象是使用.-notation(通过 启用-d .)和几个用于创建数组的命令替换来创建的。

或者您可以删除-d .并使用数组表示法的形式:

jo  Service=service1-name \
    'AWS account'=service1-dev \
    'AD Account[APP-Service1-Admin]'="$(jo -a a b)" \
    'AD Account[APP-Service1-View]'="$(jo -a c d)"
Run Code Online (Sandbox Code Playgroud)