使用jq和map将具有嵌套对象的JSON个对象转换为Name=Value格式

Using jq and map to convert JSON objects with nested objects to Name=Value format

完全坚持这一点。

我有 JSON 像这样:

{
  "create_option": "Restore",
  "disk_iops_read_write": 120,
  "disk_mbps_read_write": 25,
  "tags": {
    "Monitor": "No",
    "RSVaultBackup": "2dc504bd"
  }
}

和下面的jq

.|to_entries|map("nfs-0_\(.key)=\"\(.value)\"")|.[]

我已经做到了

nfs-0_create_option="Restore"
nfs-0_disk_iops_read_write="120"
nfs-0_disk_mbps_read_write="25"
nfs-0_tags="{"Monitor":"No","RSVaultBackup":"2dc504bd"}"

但 nfs-0_tags 行部分也需要采用名称=值格式。我想要结束的是这个

nfs-0_create_option="Restore"
nfs-0_disk_iops_read_write="120"
nfs-0_disk_mbps_read_write="25"
nfs-0_tags={Monitor="No", VaultBackup="2dc504bd"}

我觉得我应该能够递归地应用地图,但对于我来说,我无法弄清楚如何实现。

有什么想法吗?

谢谢:)

编辑:

好的,我想我现在离这个更近了一点

.|.tags |= (to_entries | map("\(.key) = \(.value)"))|to_entries|map ("\(.key) = \(.value)")|.[]

我现在得到

create_option = Restore
disk_iops_read_write = 120
disk_mbps_read_write = 25
tags = ["Monitor = No","RSVaultBackup = 2dc504bd"]

但我需要花括号 {} 中的标签行,其中键不加引号,值加引号。像这样

nfs-0_tags={Monitor="No", VaultBackup="2dc504bd"}

编辑:

我仍然希望输出看起来像这样

nfs-0_create_option="Restore"
nfs-0_disk_iops_read_write="120"
nfs-0_disk_mbps_read_write="25"
nfs-0_tags={Monitor="No", VaultBackup="2dc504bd"}

jq 运行后

act.jq中:

def f:
 if .value|type=="object" then
  "nfs-0_\(.key)={\([.value|to_entries|.[]|"\(.key)=\"\(.value)\""]|join(","))}"
 else
  "nfs-0_\(.key)=\"\(.value)\""
 end;

to_entries|.[]|f

调用:

jq -rf act.jq file.json

使用type检查我们是否应该下去。如果.value的类型是object那么我们再拆分一次,然后收集结果;否则我们只是对其进行插值。您还可以内联编写 f 函数(即,在 to_entries|.[] 之后)。

这是一个允许任意深度嵌套的解决方案,并说明了递归内部函数的使用:

def pairs:
  def q:
    if type == "string" then tojson
    elif type == "number" then "\"\(.)\""
    else . end;
  def ip:
    if type == "object"
    then "{" + (to_entries | map("\(.key)=\(.value|ip)") | join(",")) + "}"
    else q end;
  if type == "object"
  then to_entries[] | ("\(.key)=\(.value | ip)")
  else . end;

pairs