使用jq只从流中获取第一个json对象,不要触摸rest

使用jq只从流中获取第一个json对象,不要触摸rest,json,shell,jq,fifo,Json,Shell,Jq,Fifo,这条线帮助我解决了一个问题。但不是其他的 mkfifo xxs exec 3<>xxs ## keep open file descriptor echo '{"a":0,"b":{"c":"C"}}{"x":33}{"asd":889}' >&3 jq -nc input <&3 ## prints 1st object '{"a":0,"b":{"c":"C"}}' and reads out the rest cat <&3 ##

这条线帮助我解决了一个问题。但不是其他的

mkfifo xxs
exec 3<>xxs  ## keep open file descriptor
echo '{"a":0,"b":{"c":"C"}}{"x":33}{"asd":889}' >&3
jq -nc input <&3  ## prints 1st object '{"a":0,"b":{"c":"C"}}' and reads out the rest
cat <&3 ## prints nothing
mkfifoxxs
exec 3xxs##保持打开文件描述符
回音{“a”:0,b:{“c”:“c”}{“x”:33}{“asd”:889}>&3

jq-nc输入
jq
不必读取整个输入来获得第一个值。这可以通过向jq提供一个无穷大的值序列来验证,jq取第一个值并退出:

yes '{}' | jq -n input
不过,这个问题的假设要多一些。也就是说,
jq
可以从一个命名管道中读取一个JSON值,并停止“在该点上”读取,这样其余的值就可以被
cat
读取

mkfifo xxs
exec 3<>xxs              ## keep open file descriptor
echo '1 2 3' >&3
jq -nc input <&3 >first  ## Get first value
cat <&3 >rest            ## Nothing to show jq read all data
输入以流式方式处理(一次一个输入值),您可以通过管道将
stdout
和/或
stderr
传输到其他内容。尽管整个输入必须是有效的JSON,并且在通过
jq
(与上面的cat不同)时会被美化


如果不需要从命名管道中读取,并且您可以从文件中读取输入。然后,您可以在两个单独的调用中访问第一个值和其余值

echo '1 2 3' > in
jq -n 'input' in >first
jq -n 'input | inputs' in >rest
如果以流处理为目标,那么也可以在一个增量处理其输入的
jq
脚本中完成所有操作


这一切都假定为顶级值。不过,
jq
也可以使用
--stream
选项以增量方式处理嵌套结构。

您可能不能
jq
的输入功能有限,据我所知,无法将其实际读取的内容限制在其过滤器所需的最低限度。
jq-n“input”
将从传入字符串中提取单个对象,但只有在读取了至少足够的数据才能在该数据中找到完整的JSON值之后,从 MangJJ >:“此时JQ对I/O的支持最小,主要是在读取输入时的控制形式。”同时,我想知道这是一个真正的问题还是一个xy问题()。在任何情况下,如果您需要解决方法,我建议使用jq将JSON拆分为两个(或更多——取决于您实际尝试执行的操作)单独的文件…有一个生产者将JSON写入流(管道),在我这边,我需要一个接一个地处理它们,换句话说,过滤输入流、处理并生成输出。我应该更新问题来描述细节。你误解了问题。问题不在于如何只输出第一个输入,而在于如何从输入中读取不超过第一个输出的内容。@chepner我明白你的意思了。我不会依赖于
jq
从输入中“精确”读取一个值,因为它必须一次调用
read(2)
一个字节才能不通过第一个对象。我能想到的最接近的事情就是将其余的输出到stdout。尽管这必须是有效的JSON,并且将由
jq
重新格式化。我试着澄清一下。您假设
中的输入
,可以重新打开或重置为流的开头。OP的情况并非如此,他使用的是命名管道。
echo '1 2 3' > in
jq -n 'input' in >first
jq -n 'input | inputs' in >rest