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(a
、b
)添加到 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'
另一种方法是使用 inputs
,它会立即为您提供所有输入文档。然而,这将需要迭代它(input[]
而不是 .[]
)并使用 --null-input
或 -n
标志来避免吞噬第一个元素:
jq -n '["a","b"], (inputs[] | [.k1.k2,.k3.k2]) | @csv'
注意:在使用 @csv
生成输出时,您可能还想使用 --raw-output
或 -r
标志来生成原始文本而不是 JSON(因为我已经在演示中做了)。
我正在使用这种格式从 json
中提取密钥:
[
{
"k1":{"k2":4},
"k3":{"k2":6}
}
]
[
{
"k1":{"k2":4},
"k3":{"k2":6}
}
]
我正在使用此命令 ["a","b"], (.[] | [.k1.k2,.k3.k2]) | @csv
提取两个键并将两个 header(a
、b
)添加到 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'
另一种方法是使用 inputs
,它会立即为您提供所有输入文档。然而,这将需要迭代它(input[]
而不是 .[]
)并使用 --null-input
或 -n
标志来避免吞噬第一个元素:
jq -n '["a","b"], (inputs[] | [.k1.k2,.k3.k2]) | @csv'
注意:在使用 @csv
生成输出时,您可能还想使用 --raw-output
或 -r
标志来生成原始文本而不是 JSON(因为我已经在演示中做了)。