【问题标题】:Match string between curly brackets, if including pattern匹配大括号之间的字符串,如果包含模式
【发布时间】:2021-04-16 11:19:58
【问题描述】:

在日志中,我想匹配所有类型为“sync.out.notify.job.status”的 json 对象并打印它们。我在 Mac (zsh) 上。

我试过了:grep -Eo \{.+"sync\.out\.notify\.job\.status".+\}

Mon Jan 11 2021 13:08:46 GMT+0100 (Central European Standard Time) CoreSyncNotifications: sync.out.notify.job.status:
{
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "syncing",
  "minorstate": "transferring",
  "requestid": "45768456-bd58-4cb5-9dff-dfgjfgdj456",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}
Mon Jan 11 2021 13:08:46 GMT+0100 (Central European Standard Time) Vulcan: <- COSY 4.3: sync.out.notify.job.status
Mon Jan 11 2021 13:08:46 GMT+0100 (Central European Standard Time) CoreSyncNotifications: sync.out.notify.job.status:
{
  "errors": "",
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "idle",
  "minorstate": "complete",
  "requestid": "4856658fdgh-efb3-4da9-b5f5-4856658fgj",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}
Mon Jan 11 2021 13:08:46 GMT+0100 (Central European Standard Time) WebSocketServer: client_7: SEND syncstate creative_cloud: ok

【问题讨论】:

  • 你想对匹配的块做什么?打印它们?删除它们?修改它们?请edit您的问题提供您发布的示例输入的预期输出。

标签: json regex awk grep


【解决方案1】:

grep 通常只在单行中搜索模式,除非您在gnu grep 中使用-z 选项。

你可以试试这个gnu awk 命令:

awk -v RS='(^|\n){[^}]+?sync.out.notify.job.status[^}]+}(\n|$)' 'RT {printf "%s", RT}' file

{
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "syncing",
  "minorstate": "transferring",
  "requestid": "45768456-bd58-4cb5-9dff-dfgjfgdj456",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}

{
  "errors": "",
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "idle",
  "minorstate": "complete",
  "requestid": "4856658fdgh-efb3-4da9-b5f5-4856658fgj",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}

【讨论】:

  • 这适用于我的示例,但日志比这要复杂一些。我更新了示例。
  • nit:[^}]+? 不只是[^}]*
  • @jthill:不,[^}]+?[^}]* 不同。不同的是贪婪
  • 我在文档中没有看到任何例外,+ 的区别仅在于需要至少一个匹配项,你从哪里得到这个?
  • [^}]+? 是一个重复元字符 + 后跟第二个重复元字符 ? 这是 ERE 中未定义的行为,因此任何 awk 变体对它的处理取决于提供该 awk 的人,但? 可能会被忽略。 {[^}] 可能 也可能是未定义的行为,因为{ 是 RE 间隔定义的开始,但在这里它后面没有 RE 间隔(例如 {3,7}),我总是逃避{ 或将其括在括号表达式中,即使只是为了读者清楚,所以我不确定它是否按原样定义。
【解决方案2】:

假设您要打印匹配的块,您可以轻松而可靠地使用像 jq 这样的 JSON 感知工具:

$ grep -v '^[[:alpha:]]' file | jq 'select(.type=="sync.out.notify.job.status")'
{
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "syncing",
  "minorstate": "transferring",
  "requestid": "45768456-bd58-4cb5-9dff-dfgjfgdj456",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}
{
  "errors": "",
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "idle",
  "minorstate": "complete",
  "requestid": "4856658fdgh-efb3-4da9-b5f5-4856658fgj",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}

这是从 { 到 } 到管道到 jq 的另一种方法:

$ sed -n '/^{/,/^}/p' file
{
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "syncing",
  "minorstate": "transferring",
  "requestid": "45768456-bd58-4cb5-9dff-dfgjfgdj456",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}
{
  "errors": "",
  "cloudid": "00000000-0000-0000-0000-000000000000",
  "job": "files",
  "majorstate": "idle",
  "minorstate": "complete",
  "requestid": "4856658fdgh-efb3-4da9-b5f5-4856658fgj",
  "type": "sync.out.notify.job.status",
  "userid": "XXXXXXXXXXXXXXXXXXXXXXXX@AdobeID",
  "version": "1.1.43711"
}

我通常不建议使用范围表达式而不是使用标志,但在这种情况下,因为这就是你要做的一切,它可能没问题。

【讨论】:

  • 哇,太好了。我仍然收到解析错误。我认为这是因为grep -v '^[[:alpha:]]' file 输出如下行:&lt;- [SERVICE_IS_INACTIVE] Network request in inactive state
  • 然后更改我在 grep 中使用的正则表达式以适应您的实际输入。创建它时我所要做的就是您提供的示例输入。我也添加了另一种获取 json 部分的方法,但它只是基于您到目前为止显示的输入,
猜你喜欢
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多