使用 jq 忽略无法解析的 JSON

Ignore Unparseable JSON with jq

我正在使用 jq 来解析我的一些日志,但是由于各种原因无法解析某些日志行。有没有办法让 jq 忽略这些行?我似乎找不到解决办法。我尝试使用某些人推荐的 --seq 参数,但 --seq 忽略了我文件中的所有行。

假设每个日志条目正好是一行,您可以使用 -R--raw-input 选项告诉 jq 不解析这些行,之后您可以在前面添加 fromjson? |到你的过滤器,让 jq 尝试将每一行解析为 JSON 并丢弃那些错误的。

FAQ page 上有几个问答涉及 "invalid JSON" 的主题,但请特别参阅问题:

Is there a way to have jq keep going after it hits an error in the input file?

特别是,这显示了如何使用 --seq。

但是,从您提供的稀疏细节来看(SO recommends 给出了一个最小的例子),似乎简单地使用 inputs 可能更好。这个想法是一次处理一个 JSON 实体,使用 "try/catch",例如

def handle: inputs | [., "length is \(length)"] ;
def process: try handle catch ("Failed", process) ;
process  

调用 jq 时不要忘记使用 -n 选项。

另见 Processing not-quite-valid JSON

我有日志流,其中一些消息采用 json 格式。 我想通过 jq 传送 json 消息,然后回显其余的。

json 条消息位于 单行

解决方案:使用 grep 和 tee 将行分成两个流,以“^{”开头的行通过 jq 管道,其余的只是回显到终端。

kubectl logs -f web-svjkn | tee >(grep -v "^{") | grep "^{" | jq .

cat logs | tee >(grep -v "^{") | grep "^{" | jq .

解释: tee 生成第二个流,并且 grep -v 打印非 json 信息,第二个 grep 仅将看起来像 json 左括号的内容通过管道传递给 jq.

这是一个旧线程,但这里有另一个完全在 jq 中的解决方案。这使您既可以处理正确的 json 行,也可以打印出非 json 行。

jq -R . as $line | try (fromjson | <further processing for proper json lines>) catch $line'