这非常接近请求的输出。
jq -c 'to_entries[]
| if .value|type == "object"
then .key as $k
| .value
| to_entries[]
| ["\($k).\(.key)", (.value|type)]
else [.key, (.value|type)]
end'
输出:
["parameter.colA","string"]
["parameter.COLB","string"]
["workRequired","number"]
["work","number"]
["updateType","string"]
主要区别在于前两行。我不认为["parameter"."colA","string'] 是有效的json。
有些类型也不同。
说明
了解这些东西如何工作的一种方法是逐步进行。所以从jq -c 'to_entries[]' 开始,看看会发生什么,然后依次添加每个步骤。 manual也不错。
在这里,我们从一个对象开始。第一个命令是to_entries[]。引用手册,当“to_entries 传递一个对象时,对于输入中的每个 k:v 条目,输出数组包括 {"key":k, "value":v}。"在末尾添加[] 意味着输出将只是to_entries 生成的数组中的对象。所以这是第一步之后的输出:
{"key":"parameter","value":{"colA":"No","COLB":"No"}}
{"key":"workRequired","value":0}
{"key":"work","value":0}
{"key":"updateType","value":"AUTO"}
现在我们有四个对象。一个包含另一个对象。最初的问题涉及包含对象的对象。问题是在最终输出中将包含对象的键与包含对象的键结合起来。
条件if .value|type == "object" 标识包含对象的对象。
满足此条件时,.key as $k 将包含对象的“key”键的值保存为名为 $k 的变量。
然后我们对包含的对象重复to_entries[]。包含对象是包含对象中键“值”的值。代码.value | to_entries[] 通过to_entries[] 过滤包含的对象。这给了我们这两个对象。
{"key":"colA","value":"No"}
{"key":"COLB","value":"No"}
要创建所需的输出,我们需要构造一个数组,该数组将保存为 $k 的包含对象的键与这两个对象的元素组合在一起。这是我们如何做到的。 (请参阅manual 中的“字符串插值”,了解引号部分的工作原理。)
["\($k).\(.key)", (.value|type)]
对于每个对象,我们保存为变量 $k 的键与对象中“键”键的值相结合。然后我们输出对象中“value”键的值的类型。
这产生了最终输出的前两行:
["parameter.colA","string"]
["parameter.COLB","string"]
现在我们转到条件的另一个分支。这将处理第一步中不包含对象的三个对象。在这里我们只是重复问题中的原始代码,因为那是令人满意的。
else [.key, (.value|type)]
这就产生了:
["workRequired","number"]
["work","number"]
["updateType","string"]
命令end 结束条件。
还有一件事。最开始的标志 -c 告诉 jq 我们想要紧凑的输出。没有它,输出在逻辑上将是相同的,但会分布在多行中。