jq删除json之前和之后的文本

时间:2017-09-07 16:15:41

标签: json sed jq

摄取另一个提供疯狂json输出的sourcetype。它开始像:

Sep  1 15:52:26 | IdentityValidationApi |  |  |  | {"header":{"tenantId":"X03LHWE3","requestType":"  ...

并且在请求和响应之间有一个管道,但两者都在同一行:

..."serverTime":"2017-09-01T19:52:24.641Z"}}} | {"responseHeader":{"tenantID":  

并且json输出以

结束
...,"fieldValue":"Engineer"}]}}} | D2C CrossCore Request-Response | IdentityValidationApi.corp-dev.com | /api/Inquiry | 172.30.68.88 |  | True

我已经尝试过使用jq .header []的jq,但它讨厌那个|在活动中间。最终目标是将整个事件摄取到Splunk中,而不在json外部使用开头或结尾文本。有人可以在这里建议任何步骤吗谢谢。

编辑:我可以使用sed来拉出行的开头,但我不确定如何将其与从末尾删除文本相结合。我能这样做吗?

2 个答案:

答案 0 :(得分:1)

jq旨在使用json数据。您的输入是不是纯json。如果您可以对输入做出某些假设,那么您可以可能处理json部分。任何输入的任何偏差都会破坏。

  1. 管道(|)仅用作整个文件的分隔符,类似于“管道分隔值”文件(la csv但没有转义序列) <登记/> jq可以将原始文件作为字符串使用,如果管道实际上仅用作分隔符,我们不必担心解析它
  2. 文件中的数据不会跨越多行,只占一行
    没有解析数据或假设文件中有任何模式,就不可能知道哪些行属于单个项目以及何时开始新的
  3. 您的json数据将始终位于psv行的固定列中
    再次,如果没有进一步处理它不在固定的地方,就不可能知道请求或响应部分在行中的位置
  4. 如果这些假设成立,你可以使用这样的东西:

    $ jq -R 'split("|") | {request:.[5]|fromjson,response:.[6]|fromjson}' input.psv
    

    这应该为您提供可以访问请求和响应对象的对象。然后你可以对它们进行操作。

答案 1 :(得分:0)

尽管Jeff's answer几乎总结了一下,但这是一个从样本数据片段汇总的具体示例。如果文件data包含

Sep  1 15:52:26 | IdentityValidationApi |  |  |  | {"header":{"tenantId":"X03LHWE3"}, "serverTime":"2017-09-01T19:52:24.641Z"} | {"responseHeader":{"tenantID": "...", "fieldValue":"Engineer"}} | D2C CrossCore Request-Response | IdentityValidationApi.corp-dev.com | /api/Inquiry | 172.30.68.88 |  | True

然后

$ jq -M -Rc './"|" | .[5] | fromjson' data

将只生成第5列的json片段:

{"header":{"tenantId":"X03LHWE3"},"serverTime":"2017-09-01T19:52:24.641Z"}

此过滤器

$ jq -M -Rc './"|" | (.[5]|fromjson) + (.[6]|fromjson)' data

将第5列和第6列中的对象合并为一个对象:

{"header":{"tenantId":"X03LHWE3"},"serverTime":"2017-09-01T19:52:24.641Z","responseHeader":{"tenantID":"...","fieldValue":"Engineer"}}