Shell jq 将 header 添加到 csv 输出中的每一行,而不仅仅是在顶部添加一次

Shell jq is adding header to every other line in csv output, not just once at the top

我正在使用这种格式从 json 中提取密钥:

[
 {
   "k1":{"k2":4},
   "k3":{"k2":6}
 }
]
[
 {
   "k1":{"k2":4},
   "k3":{"k2":6}
 }
]

我正在使用此命令 ["a","b"], (.[] | [.k1.k2,.k3.k2]) | @csv 提取两个键并将两个 header(ab)添加到 csv。但是输出结果是每隔一行 header:

"\"a\",\"b\""
"4,6"
"\"a\",\"b\""
"4,6"

你可以在这个jq play中看到这个。我怎样才能将过滤器更改为仅将 header 放在第一行?

由于您的 json 中有流,您需要 inputs 而不是 .[]

jq -nr '(["a","b"], (inputs | map(.k1.k2,.k3.k2))) | @csv' input-json

您的输入是 JSON 文档流。因此,您的过滤器会为每个文档执行一次,包括构建 headers.

一种解决方案是使用--slurp-s 选项将流作为数组读入。然而,这将需要在您的迭代中更深入一层(.[][] 而不仅仅是 .[]):

jq -s '["a","b"], (.[][] | [.k1.k2,.k3.k2]) | @csv'

Demo

另一种方法是使用 inputs,它会立即为您提供所有输入文档。然而,这将需要迭代它(input[] 而不是 .[])并使用 --null-input-n 标志来避免吞噬第一个元素:

jq -n '["a","b"], (inputs[] | [.k1.k2,.k3.k2]) | @csv'

Demo

注意:在使用 @csv 生成输出时,您可能还想使用 --raw-output-r 标志来生成原始文本而不是 JSON(因为我已经在演示中做了)。