使用值映射标题

  • 本文关键字:标题 映射 json jq
  • 更新时间 :
  • 英文 :


我有一个"一种JSON"(我不知道这是否是一种标准格式),我想用jq解析。我已经尝试了很多变化,但我无法让它与 jq 一起使用。

"JSON"如下所示:

{
"headers" : [
"key1",
"key2",
"key3",
],
"rows" : [
[
"value1",
"value2",
"value3"
],
[
"value1",
"value2",
"value3"
],
[
"value1",
"value2",
"value3"
]
],
"total_rows" : "3"
}

我想使用标题部分作为每行的键。所以输出应该看起来像这样:

[
"key1" : "value1",
"key2" : "value2",
"key3" : "value3"
],
[
"key1" : "value1",
"key2" : "value2",
"key3" : "value3"
],
[
"key1" : "value1",
"key2" : "value2",
"key3" : "value3"
]
  1. 给定输入中有一个多余的逗号。以下假设它已被删除。
  2. 请求的输出不是有效的 JSON,因此下面假设目的是让输出是对象数组(如下所示)。 当然,其他输出格式也是可能的,包括原始发布中给出的格式。
  3. 下面使用了jq的"map"和"reduce"过滤器;如果您不熟悉它们中的任何一个,请参阅jq文档。

  4. 为清楚起见,以下解决方案使用帮助程序函数将值数组与键名称数组组合在一起:

    def convolve(headers):
    . as $in
    | reduce range(0; length) as $i ({}; . + {(headers[$i]): $in[$i]} );
    
  5. 定义convolve/1后,我们现在可以创建对象数组:

    .headers as $h | .rows | map( convolve($h) )
    
  6. 使用上面的jq程序在文件(比如program.jq),将JSON放在一个名为input.json的文件中,调用:

    jq -f program.jq input.json
    

    生产:

    [
    {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
    },
    {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
    },
    {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3"
    }
    ]
    
  7. 这是convolve的无约化定义;它假设transpose/0的可用性,包含在 jq 1.5 及更高版本中:

    def convolve(headers):
    [., headers] | transpose | map( {(.[0]): .[1]} ) | add;
    
  8. 以下代码片段在功能上等效于上面的 5.

    .headers as $h
    | reduce .rows[] as $row ([]; . + [$row|convolve($h)])
    

这是一个使用递归函数obj从键和值数组构建对象的解决方案。

def obj($keys; $values):
if   $keys|length < 1
then {} 
else {($keys[0]): $values[0]} + obj($keys[1:]; $values[1:])
end
;
[ obj(.headers; .rows[]) ]

最新更新