需要 jq 帮助将半格式错误但非常简单的 json 文件转换为 csv

Need jq help to turn a semi-malformed but very simple json file into csv

我有点问题。我已经针对对象检测器吐出的一大组 json 文件尝试了 jq -r 的许多不同迭代,但我就是无法让它足够快乐地给我一个 csv 文件。我将这些庞大的文件简化为下面一个非常简短的示例,具有完全相同的数据结构(注意,诸如“书”、“人”、“动物”之类的名称在脚本中不断变化,所以如果有办法在不对命令中的键进行硬编码的情况下执行此操作,这是最需要但不是必需的)

示例:

{
    "/src/files/image_1.png": {
        "book": 0.01711445301771164,
        "person": 0.000330559065533263624,
        "place": 0.9814764857292175,
        "animal": 1.8662762158783153e-05,
        "vehicle": 0.0010597968939691782
    },
    "/src/files/image_2.png": {
        "book": 0.23741412162780762,
        "person": 0.1587823033328247,
        "place": 0.59659236669504,
        "animal": 0.0036556862760335207,
        "vehicle": 0.003555471543222666
    }
}

理想情况下,我想制作一个表格格式如下所示的 csv 文件:

File Book Person Place Animal Vehicle
/src/files/image_1.png 0.01711445301771164 0.000330559065533263624 0.9814764857292175 1.8662762158783153e-05 0.0010597968939691782
/src/files/image_2.png 0.23741412162780762 0.1587823033328247 0.59659236669504 0.0036556862760335207 0.003555471543222666
. as $data |
keys_unsorted as $ids |
( .[ $ids[0] ] | keys_unsorted ) as $fields |
(
   [ "id", $fields[] ],
   ( $ids[] | [ ., $data[.][$fields[]] ] )
) | @csv

jqplay

keys_unsorted as $ids |
( .[ $ids[0] ] | keys_unsorted ) as $fields |
(
   [ "id", $fields[] ],
   ( to_entries[] | [ .key, .value[$fields[]] ] )
) | @csv

jqplay

两者都不能很好地处理空输入 ({})。


为了比较,@peak 的 headers 解决方案是

keys_unsorted as $ids |
( .[ $ids[0] ] | keys_unsorted ) as $fields |
(
   [ "id", $fields[] ],
   ( $ids[] as $id | [ $id, .[$id][$fields[]] ] )
) | @csv

jqplay

它也不能很好地处理空输入 ({})

下面的解决方案比其他方式更棘手,因为它是“data-driven”(在 jq 程序中 hard-coded 除了“文件”之外没有其他键名),同时不假设内部键的顺序一致:

  keys_unsorted as $outer
  | (.[$outer[0]] | keys_unsorted) as $inner
  | ["File"] + ($inner|map((.[:1]|ascii_upcase) + .[1:])),
    ($outer[] as $k
     | [$k] + [.[$k] | .[$inner[]]])
  | @tsv

您当然希望使用 @csv 而不是 @tsv

(有许多 SO 问题说明了如何添加 headers,例如,以下说明如何在不对它们进行硬编码的情况下添加它们,并在主要 [= 下方动态生成“-”行22=]: How to format a JSON string as a table using jq?)