使用 jq 从 json 生成 "table"

generating "table" from json using jq

从上一个问题中取回我的示例数据之一:

{
  "countries": [
    {
      "countryName": "CZ",
      "cities": [
        {
          "cityName": "Prague",
          "streets": [
            {
              "streetName": "Norská"
            },
            {
              "streetName": "Slovenská"
            }
          ]
        }
      ]
    },
    {
      "countryName": "FR",
      "cities": [
        {
          "cityName": "Paris",
          "streets": [
            {
              "streetName": "rue piat"
            },
            {
              "streetName": "rue lesage"
            }
          ]
        }
      ]
    }
  ]
}

我想使用 jq 从这些数据中生成 plaintext/asciidoc/markdown table,但我想念一些基本的方法。给定列中的重复是我没有得到的。

因此预期的输出可能如下所示:

CZ Prague Norská
CZ Prague Slovenská
FR Paris rue piat
FR Paris rue lesage

即。如何遍历顶级数组 countries,从中选择字段 countryName,如何遍历包含在 countries 数组元素中的字段 cities 并从中选择 cityName等得到三元组的结果数组,然后可以将其处理成所需的输出文本。

编辑:

但出于某种原因,以下使用@csv 的方法对我不起作用。

jq '[(.countries[] | .countryName as $country| .cities[] | .cityName as $city | .streets[] | [$country,$city,.streetName])] | @csv' < /tmp/sampleData.json

如果有任何改进建议,我将不胜感激。

EDIT2:要使@csv 工作,它必须用数组(它是)而不是数组数组来提供。对命令式编程风格的误解。无论如何,这个是正确的:

jq '[(.countries[] | .countryName as $country| .cities[] | .cityName as $city | .streets[] | [$country,$city,.streetName])] | .[] | @csv' < /tmp/sampleData.json 

可以稍微简化您的 jq 解决方案,同时提高其效率:

.countries[]
| .countryName as $country
| .cities[]
| .cityName as $city
| .streets[]
| [$country, $city, .streetName]
| @csv

结合 -r command-line 选项,这当然会生成有效的 CSV,但您的 Q 表示偏好删除(不必要的?)引号。对于显示的示例数据,您可以将 @csv 替换为 join(","),但通常情况下,必须注意 CSV 特有的逗号和其他字符。

一般情况

以下似乎可以处理一般情况,但依赖于 sed 来处理关于引号和嵌入换行符的 CSV 约定,并且尚未经过彻底测试:

< sampleData.json jq -r '
def q:
  if type == "string" and test("[,\n\"]")
  then tojson 
  else . end;
  
.countries[]
| .countryName as $country
| .cities[]
| .cityName as $city
| .streets[]
| [$country, $city, .streetName]
| map(q)
| join(",")
' | sed -e 's/\\"/""/g' -e 's/\n/\
/g'