使用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
完全坚持这一点。
我有 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