使用 jq 将 json 地图转换为 csv

Converting json map to csv using jq

输入

{"key1": ["value1", "value2"], "key2": ["value3"]}

期望的输出

key1, value1
key1, value2
key2, value3

很难弄清楚 jq 命令来实现这个...我已经尝试过 map,因为,to_entries 过滤器以各种组合但没有运气。

我删除了您的 JSON 对象周围的一对额外括号,以使其成为有效的 JSON。所以,从这个开始:

{
  "key1": [ "value1", "value2" ],
  "key2": [ "value3" ]
}

我们应用 to_entries,结果是:

[
  {
    "key": "key1",
    "value": [ "value1", "value2" ]
  },
  {
    "key": "key2",
    "value": [ "value3" ]
  }
]

然后,我们 map 每个条目,并展开 ([]) .value 数组,为其每个元素创建一个单独的对象 (map({key, value: .value[]}) ).这给了我们:

[
  {
    "key": "key1",
    "value": "value1"
  },
  {
    "key": "key1",
    "value": "value2"
  },
  {
    "key": "key2",
    "value": "value3"
  }
]

之后,对于这些对象中的每一个,我们都需要一个包含其值的数组,因为这是 @csv 过滤器所期望的。这只是映射到一个数组对象,如 map([.key, .value]),它给我们:

[
  [ "key1", "value1" ],
  [ "key1", "value2" ],
  [ "key2", "value3" ]
]

最后,我们传播 ([]) 数组的数组(因为 @csv 需要单独的数组)并且我们将 @csv 传递给它。完整脚本如下所示:

jq -r 'to_entries | map({key, value: .value[]}) | map([.key, .value])[] | @csv' test.json

及其输出:

"key1","value1"  
"key1","value2"  
"key2","value3"

您可以跳过几个建立行的步骤。

$ jq -r 'to_entries[] | { key, value: .value[] } | [ .key, .value ] | @csv'

在 jq 1.5 中,您可以利用新的 combinations 过滤器来生成键和值的组合。

$ jq -r 'to_entries[] | [ [.key], .value ] | combinations | @csv'

这是一个仅使用 jq 的 [] 运算符和 \() 字符串插值的简短解决方案。与 jq -r 标志一起使用以避免在最终输出中出现额外的引号。

  . as $v
| keys[]
| "\(.), \($v[.][])"