jq - 将 json 转换为 csv 问题。无法转换 sub-array

jq - converting json to csv issue. Unable to convert sub-array

我一直在努力理解 jq 语法,但我对它有疑问。我正在尝试像其他人一样将 json 转换为 csv。我在论坛上发现了很多条目,但其中 none 似乎对我有用。当我缩小过滤器范围时,我总是得到一些错误或部分结果。

目标:

  1. 我从 https://www.wunderground.com/ 使用 https://api.weather.com/v2/pws/history/hourly?stationId=IBONIE3&format=json&units=m&date=20210731&apiKey="
  2. 我想将此数据转换成 csv

我从源头得到的是 1 小时时间跳跃中 1 天的数据。数据存储在 'observations' 下。看起来像这样:

{"observations":[
    {
      "stationID": "IBONIE3",
      "tz": "Europe/Warsaw",
      "obsTimeUtc": "2021-07-31T21:59:50Z",
      "obsTimeLocal": "2021-07-31 23:59:50",
      "epoch": 1627768790,
      "lat": 52.203785,
      "lon": 20.618021,
      "solarRadiationHigh": 0,
      "uvHigh": 0,
      "winddirAvg": 257,
      "humidityHigh": 74,
      "humidityLow": 71,
      "humidityAvg": 71,
      "qcStatus": 1,
      "metric": {
        "tempHigh": 20,
        "tempLow": 20,
        "tempAvg": 20,
        "windspeedHigh": 8,
        "windspeedLow": 0,
        "windspeedAvg": 2,
        "windgustHigh": 12,
        "windgustLow": 0,
        "windgustAvg": 3,
        "dewptHigh": 15,
        "dewptLow": 15,
        "dewptAvg": 15,
        "windchillHigh": 20,
        "windchillLow": 20,
        "windchillAvg": 20,
        "heatindexHigh": 20,
        "heatindexLow": 20,
        "heatindexAvg": 20,
        "pressureMax": 994.58,
        "pressureMin": 993.91,
        "pressureTrend": 0,
        "precipRate": 0,
        "precipTotal": 0
      }

}]}

显然这只是单个文件中 24 个条目中的 1 个。

当我这样做时:

cat file.json | jq '.observations[0],.observations[0].metric | keys_unsorted | @csv'

"\"stationID\",\"tz\",\"obsTimeUtc\",\"obsTimeLocal\",\"epoch\",\"lat\",\"lon\",\"solarRadiationHigh\",\"uvHigh\",\"winddirAvg\",\"humidityHigh\",\"humidityLow\",\"humidityAvg\",\"qcStatus\",\"metric\""
"\"tempHigh\",\"tempLow\",\"tempAvg\",\"windspeedHigh\",\"windspeedLow\",\"windspeedAvg\",\"windgustHigh\",\"windgustLow\",\"windgustAvg\",\"dewptHigh\",\"dewptLow\",\"dewptAvg\",\"windchillHigh\",\"windchillLow\",\"windchillAvg\",\"heatindexHigh\",\"heatindexLow\",\"heatindexAvg\",\"pressureMax\",\"pressureMin\",\"pressureTrend\",\"precipRate\",\"precipTotal\""

我确实得到了正确格式的 header,但是当我这样做时

cat file.json | jq -r '.observations[] | map(values) | @csv

jq: error (at <stdin>:1): object ({"tempHigh"...) is not valid in a csv row

我收到错误消息。这对我来说很明显,因为这进入了 sub-array 称为指标,这是显示错误的地方。我只能通过 运行 获得这些指标:

cat file.json | jq -r '.observations[].metric | map(values) | @csv
20,18,19,0,0,0,0,0,0,15,14,14,20,18,19,20,18,19,994.58,994.24,0.34,0,0

跳过所有其他数据,但这不是我想要的。

如何将此度量数组转换为 non-array object? 有没有办法在单个查询中做到这一点?

显然 header 不能同时具有变量“metric”,而是 sub-array - metric 中的所有项目。我可以手动修复 header 甚至跳过它,但是如何获取整个数据,而不仅仅是指标?

如果没有键冲突,您可以将 .metric 子数组的项目整合到实际记录中:

jq -r '
  .observations[] |= (. + .metric | del(.metric))
  | (.observations[0] | keys_unsorted), (.observations[] | map(values))
  | @csv
' file.json
"stationID","tz","obsTimeUtc","obsTimeLocal","epoch","lat","lon","solarRadiationHigh","uvHigh","winddirAvg","humidityHigh","humidityLow","humidityAvg","qcStatus","tempHigh","tempLow","tempAvg","windspeedHigh","windspeedLow","windspeedAvg","windgustHigh","windgustLow","windgustAvg","dewptHigh","dewptLow","dewptAvg","windchillHigh","windchillLow","windchillAvg","heatindexHigh","heatindexLow","heatindexAvg","pressureMax","pressureMin","pressureTrend","precipRate","precipTotal"
"IBONIE3","Europe/Warsaw","2021-07-31T21:59:50Z","2021-07-31 23:59:50",1627768790,52.203785,20.618021,0,0,257,74,71,71,1,20,20,20,8,0,2,12,0,3,15,15,15,20,20,20,20,20,20,994.58,993.91,0,0,0

Demo

如果它们碰巧发生冲突,请在它们的名称中添加一些前缀以消除歧义:

jq -r '
  .observations[] |= (. + (.metric | with_entries(.key |= "metric_\(.)")) | del(.metric))
  | (.observations[0] | keys_unsorted), (.observations[] | map(values))
  | @csv
' file.json
"stationID","tz","obsTimeUtc","obsTimeLocal","epoch","lat","lon","solarRadiationHigh","uvHigh","winddirAvg","humidityHigh","humidityLow","humidityAvg","qcStatus","metric_tempHigh","metric_tempLow","metric_tempAvg","metric_windspeedHigh","metric_windspeedLow","metric_windspeedAvg","metric_windgustHigh","metric_windgustLow","metric_windgustAvg","metric_dewptHigh","metric_dewptLow","metric_dewptAvg","metric_windchillHigh","metric_windchillLow","metric_windchillAvg","metric_heatindexHigh","metric_heatindexLow","metric_heatindexAvg","metric_pressureMax","metric_pressureMin","metric_pressureTrend","metric_precipRate","metric_precipTotal"
"IBONIE3","Europe/Warsaw","2021-07-31T21:59:50Z","2021-07-31 23:59:50",1627768790,52.203785,20.618021,0,0,257,74,71,71,1,20,20,20,8,0,2,12,0,3,15,15,15,20,20,20,20,20,20,994.58,993.91,0,0,0

Demo