如何使用 jq 将对象数组格式化为分隔的键值列表

How to use jq to format array of objects to separated list of key values

我如何(一般地)将下面的输入文件转换为下面的输出文件,使用 jq.输出文件的记录格式为:array_index |钥匙 |值

输入文件:

[{"a": 1, "b": 10},
 {"a": 2, "d": "fred", "e": 30}]

输出文件:

0|a|1
0|b|10
1|a|2
1|d|fred
1|e|30
< file.json jq -r 'to_entries
                   | .[] 
                   | .key as $k
                   | ((.value | to_entries )[]
                      | [$k, .key, .value])
                   | @csv'

输出:

0,"a",1
0,"b",10
1,"a",2
1,"d","fred"
1,"e",30

您只需删除双引号即可。

to_entries 可用于以同时给出元素的键(索引)和值的方式遍历数组和对象的元素。

jq -r '
   to_entries[] |
   .key as $id |
   .value |
   to_entries[] |
   [ $id, .key, .value ] |
   join("|")
'

Demo 在 jqplay

join("|") 替换为 @csv 以获得正确的 CSV。

这是一个使用 tostream 的解决方案,它创建了一系列路径及其值。使用 selectflatten 来过滤掉那些值以对齐两者,并使用 join 输出格式:

jq -r 'tostream | select(has(1)) | flatten | join("|")'
0|a|1
0|b|10
1|a|2
1|d|fred
1|e|30

Demo

或者一个非常相似的,使用paths获取路径,scalars用于过滤器,getpath用于相应的值:

jq -r 'paths(scalars) as $p | [$p[], getpath($p)] | join("|")'
0|a|1
0|b|10
1|a|2
1|d|fred
1|e|30

Demo