【问题标题】:jq remove text before and after jsonjq 删除 json 前后的文本
【发布时间】:2017-09-07 16:15:41
【问题描述】:

摄取另一种提供疯狂 json 输出的源类型。开头是这样的:

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,使用 jq .header[],但它讨厌那个 |在事件的中间。最终目标是将整个事件摄取到 Splunk 中,而没有 json 之外的开始或结束文本。有人可以在这里建议任何步骤吗?谢谢。

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

【问题讨论】:

    标签: json sed jq


    【解决方案1】:

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

    1. 管道 (|) 仅用作整个文件的分隔符,有点像“管道分隔值”文件(a la csv,但没有转义序列)
      jq 可以将原始文件作为字符串来消费,如果管道真的只用作分隔符,我们不必担心解析它
    2. 文件中的数据不跨越多行,只占一行
      如果不解析数据或假设文件中的任何模式,将无法知道哪些行属于单个项目以及新项目何时开始
    3. 您的 json 数据将始终位于 psv 行的固定列中
      同样,如果不在行中,则无法知道请求或响应部分的位置' t 在固定的地方,无需进一步处理

    如果这些假设成立,您可能会使用这样的方法:

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

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

    【讨论】:

    • 杰夫,太棒了。 [5] 和 [6] 是什么意思?我可能对在脚本中运行它还有其他问题,但这太棒了,谢谢!
    • 我们在文件中逐行读取整个字符串 (-R)。对于这些行中的每一行,我们通过管道将其拆分为一个数组 (split("|"))。从我在您的问题中可以看出,请求和响应分别位于第 6 列和第 7 列。
    • 啊。我了解到这些数据是通过 syslog 进入我的 syslog 服务器上的文件的。我需要在这些事件进入时(或尽快)摄取这些事件。我找到了一个 [stackoverflow.com/a/18341108/6752652](script),它将监视 syslog 文件输出,并创建一个带有清理后的输出的新文件。我确信有更好的方法,但我不知道。我正在使用未安装 inotify-tools 的 Red Hat 6.9。
    【解决方案2】:

    虽然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"}}
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多