Json 如何使用jq创建具有多个标题和详细信息行的CSV?

Json 如何使用jq创建具有多个标题和详细信息行的CSV?,json,csv,jq,Json,Csv,Jq,我希望使用jq以CSV格式输出,但是对于多个标题,后跟多个详细信息。我在Stack Overflow上已经看到的解决方案提供了一种插入单个头的方法,但是我没有找到任何适用于多个头的方法 为了让您了解我所说的内容,下面是一些JSON输入示例: [ { "HDR": [1, "abc"], "DTL": [ [101,"Descr A"], [102,"Descr B"] ] }, { "HDR": [2, "def"], "DTL": [ [103,"Descr C"],

我希望使用jq以CSV格式输出,但是对于多个标题,后跟多个详细信息。我在Stack Overflow上已经看到的解决方案提供了一种插入单个头的方法,但是我没有找到任何适用于多个头的方法

为了让您了解我所说的内容,下面是一些JSON输入示例:

[
  {
  "HDR": [1, "abc"],
  "DTL": [ [101,"Descr A"], [102,"Descr B"] ]
  }, {
  "HDR": [2, "def"],
  "DTL": [ [103,"Descr C"], [104,"Descr D"] ]
  }
]
期望输出:

HDR|1|abc
DTL|101|Descr A
DTL|102|Descr B
HDR|2|def
DTL|103|Descr C
DTL|104|Descr D
我不知道这是否可行,但到目前为止,我的方法是尝试创建一个过滤器,以提供以下内容,因为将其转换为我需要的内容将是微不足道的:

["HDR", 1, "abc"]
["DTL", 101, "Descr A"]
["DTL", 102, "Descr B"]
["HDR", 2, "def"]
["DTL", 103, "Descr C"]
["DTL", 104, "Descr D"]
说得清楚一点,我知道如何在任何数量的脚本语言中做到这一点,但如果可能的话,我真的尝试使用一个jq过滤器

编辑:我应该澄清,我不一定需要将“HDR”和“DTL”键复制到CSV中(我可以硬编码这些键),因此,如果示例JSON可以使问题变得更容易,那么它可能看起来像这样

[
  [
    [1, "abc"],
    [[101,"Descr A"], [102,"Descr B"]]
  ], [
    [2, "def"],
    [[103,"Descr C"], [104,"Descr D"]]
  ]
]
编辑:这个过滤器从技术上用我提供的第二个样本数据回答了这个问题(最后一个,这只是数组,没有对象),但我仍然希望有更好的答案,如果没有其他原因,只是头长度必须硬编码,并将HDR放入两组数组中,以便可以展平()他后来觉得不对。但我会把它留在这里作为参考


[]|展平(1)[[[“HDR”]+.[0:2]]]为$HDR.[2:]为$dtl |$dtl |映射([[“dtl”]+.])为$dtl |$HDR+$dtl |展平(1).[]join(|“)
假设您选择了
作为分隔符,因为您的任何代码字段都不能包含<124code>

jq -r 'map(["HDR"]+.HDR, ["DTL"] + .DTL[])[] | join("|")' data.json
  • map
    为每个对象生成多个数组元素
  • .DTL[]
    确保每个子列表前面都有
    “DTL”
  • []
    展平
    映射的结果

这比我所拥有的要好得多。我喜欢它。谢谢作为记录,在我正在处理的实际项目中,它是以制表符分隔的(制表符将被剥离),但我认为管道可以作为更好的说明。此外,我还要感谢您解释过滤器的每个组件都在做什么。这真的很有帮助。啊,用
@tsv
替换
join(“|”)
,然后。如果字段本身可能包含制表符,那么这将负责引用字段。实际上,我错了。它将以0x000F分隔。读取此输出的应用程序是一个旧的应用程序,根本没有转义字段,因此必须使用一个不常见的字符作为分隔符。幸运的是,jq可以轻松做到这一点。再次感谢!