使用 jq --stream 获取 JSON 对象的值
Get value of JSON object using jq --stream
我正在尝试使用 jq --stream
提取 JSON 对象的值,因为真实数据的大小可以达到数 GB。
这是我用于测试的 JSON,我想在其中提取 item
的值:
{
"other": "content here",
"item": {
"A": {
"B": "C"
}
},
"test": "test"
}
我正在使用的 jq
选项:
jq --stream --null-input 'fromstream(inputs | select(.[0][0] == "item"))[]' example.json
但是,这个命令没有得到任何输出。
我发现一件奇怪的事情是,在 item
之后删除对象时,上面的命令似乎有效:
{
"other": "content here",
"item": {
"A": {
"B": "C"
}
}
}
结果符合预期:
❯ jq --stream --null-input 'fromstream(inputs | select(.[0][0] == "item"))[]' example.json
{
"A": {
"B": "C"
}
}
但由于我无法控制输入 JSON 这不是解决方案。
我在 MacOS 上使用 jq 1.6 版。
您没有截断流,因此在将其过滤为仅包含 .item
以下的部分后,fromstream
缺少最后的 back-tracking 项 [["item"]]
。要么在最后手动添加它(不推荐,这也会在结果中包含 top-level 对象),或者更简单,使用 1 | truncate_stream
完全去除第一层:
jq --stream --null-input '
fromstream(1 | truncate_stream(inputs | select(.[0][0] == "item")))
' example.json
{
"A": {
"B": "C"
}
}
或者,您可以使用 reduce
和 setpath
自己构建结果对象:
jq --stream --null-input '
reduce inputs as $in (null;
if $in | .[0][0] == "item" and has(1) then setpath($in[0];$in[1]) else . end
)
' example.json
{
"item": {
"A": {
"B": "C"
}
}
}
要删除顶级对象,请在末尾过滤 .item
,或者类似于 truncate_stream
,使用 [1:]
删除路径的第一项以去除第一级:
jq --stream --null-input '
reduce inputs as $in (null;
if $in | .[0][0] == "item" and has(1) then setpath($in[0][1:];$in[1]) else . end
)
' example.json
{
"A": {
"B": "C"
}
}
我正在尝试使用 jq --stream
提取 JSON 对象的值,因为真实数据的大小可以达到数 GB。
这是我用于测试的 JSON,我想在其中提取 item
的值:
{
"other": "content here",
"item": {
"A": {
"B": "C"
}
},
"test": "test"
}
我正在使用的 jq
选项:
jq --stream --null-input 'fromstream(inputs | select(.[0][0] == "item"))[]' example.json
但是,这个命令没有得到任何输出。
我发现一件奇怪的事情是,在 item
之后删除对象时,上面的命令似乎有效:
{
"other": "content here",
"item": {
"A": {
"B": "C"
}
}
}
结果符合预期:
❯ jq --stream --null-input 'fromstream(inputs | select(.[0][0] == "item"))[]' example.json
{
"A": {
"B": "C"
}
}
但由于我无法控制输入 JSON 这不是解决方案。
我在 MacOS 上使用 jq 1.6 版。
您没有截断流,因此在将其过滤为仅包含 .item
以下的部分后,fromstream
缺少最后的 back-tracking 项 [["item"]]
。要么在最后手动添加它(不推荐,这也会在结果中包含 top-level 对象),或者更简单,使用 1 | truncate_stream
完全去除第一层:
jq --stream --null-input '
fromstream(1 | truncate_stream(inputs | select(.[0][0] == "item")))
' example.json
{
"A": {
"B": "C"
}
}
或者,您可以使用 reduce
和 setpath
自己构建结果对象:
jq --stream --null-input '
reduce inputs as $in (null;
if $in | .[0][0] == "item" and has(1) then setpath($in[0];$in[1]) else . end
)
' example.json
{
"item": {
"A": {
"B": "C"
}
}
}
要删除顶级对象,请在末尾过滤 .item
,或者类似于 truncate_stream
,使用 [1:]
删除路径的第一项以去除第一级:
jq --stream --null-input '
reduce inputs as $in (null;
if $in | .[0][0] == "item" and has(1) then setpath($in[0][1:];$in[1]) else . end
)
' example.json
{
"A": {
"B": "C"
}
}