有没有办法让 jq 在遇到错误后继续前进?
Is there a way to have jq keep going after it hits an error?
我正在使用 jq 解析日志数据,偶尔日志中包含格式错误的内容(无效 json),发生这种情况时,jq 会在此时中止处理。
有没有办法让 jq 继续处理它可以处理的内容,同时通过 stderr 报告问题?
我知道如果你的 JSON 中有换行符,如果它从下一行开始,jq 可能会遇到麻烦,但在这种情况下,你最终还是会到达你找到开始的地步合法的 json 邮件,可以继续处理。
如果你有 jq 1.5,答案是:是,但一般来说,预处理(例如使用 hjson 或 any-json)会更好。
无论如何,这个想法只是利用 try/catch 功能。这是使用 inputs
过滤器的示例。请注意,通常应使用 -n 选项调用 jq 才能使其正常工作。
recover.jq
def handle: inputs | [., "length is \(length)"] ;
def process: try handle catch ("Failed", process) ;
process
bad.json
[1,2,3]
{id=546456, userId=345345}
[4,5,6]
见jq 运行:
$ jq -n -f recover.jq bad.json
[
"[1,2,3]",
"length is 3"
]
"Failed"
[
"[4,5,6]",
"length is 3"
]
使用 jq-1.5 我可以做到以下几点:
使用此示例文件:
cat << EOF > example.log
{"a": 1}
{invalid
{"b": 2}
EOF
将非 json 行输出为不带引号的字符串:
cat example.log | jq --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
"a": 1
}
{invalid
{
"b": 2
}
静默跳过非json行:
cat example.log | jq --raw-input 'fromjson?'
{
"a": 1
}
{
"b": 2
}
如果整个输入预计是单个多行 json blob,您可以添加 --slurp
。
示例文件:
cat << EOF > valid-multiline.log
{
"a": 1,
"b": 2
}
EOF
cat << EOF > invalid-multiline.log
{
asdf
"b": 2
}
EOF
产出
cat valid-multiline.log | jq --slurp --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
"a": 1,
"b": 2
}
cat invalid-multiline.log | jq --slurp --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
asdf
"b": 2
}
我正在使用 jq 解析日志数据,偶尔日志中包含格式错误的内容(无效 json),发生这种情况时,jq 会在此时中止处理。
有没有办法让 jq 继续处理它可以处理的内容,同时通过 stderr 报告问题?
我知道如果你的 JSON 中有换行符,如果它从下一行开始,jq 可能会遇到麻烦,但在这种情况下,你最终还是会到达你找到开始的地步合法的 json 邮件,可以继续处理。
如果你有 jq 1.5,答案是:是,但一般来说,预处理(例如使用 hjson 或 any-json)会更好。
无论如何,这个想法只是利用 try/catch 功能。这是使用 inputs
过滤器的示例。请注意,通常应使用 -n 选项调用 jq 才能使其正常工作。
recover.jq
def handle: inputs | [., "length is \(length)"] ;
def process: try handle catch ("Failed", process) ;
process
bad.json
[1,2,3]
{id=546456, userId=345345}
[4,5,6]
见jq 运行:
$ jq -n -f recover.jq bad.json
[
"[1,2,3]",
"length is 3"
]
"Failed"
[
"[4,5,6]",
"length is 3"
]
使用 jq-1.5 我可以做到以下几点:
使用此示例文件:
cat << EOF > example.log
{"a": 1}
{invalid
{"b": 2}
EOF
将非 json 行输出为不带引号的字符串:
cat example.log | jq --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
"a": 1
}
{invalid
{
"b": 2
}
静默跳过非json行:
cat example.log | jq --raw-input 'fromjson?'
{
"a": 1
}
{
"b": 2
}
如果整个输入预计是单个多行 json blob,您可以添加 --slurp
。
示例文件:
cat << EOF > valid-multiline.log
{
"a": 1,
"b": 2
}
EOF
cat << EOF > invalid-multiline.log
{
asdf
"b": 2
}
EOF
产出
cat valid-multiline.log | jq --slurp --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
"a": 1,
"b": 2
}
cat invalid-multiline.log | jq --slurp --raw-input --raw-output '. as $raw | try fromjson catch $raw'
{
asdf
"b": 2
}