首页 > 解决方案 > 有条件地从 Bash 中类似 JSON 的键值对中 grep 值

问题描述

我正在使用返回 JSON 数据的 API。数据通常在末尾缺少几个字符,因此它在技术上是“类似 JSON”的,因为它的格式有点不正确。

grep我可以在我的 Bash 脚本中使用这样的方法从中提取感兴趣的字段:

grep -Po '"username": *\K"[^"]*"' jsonraw > jsonclean

尽管 JSON 被略微截断,但效果很好。唯一的问题是它返回每条记录,而我想让它以另一个键值对为条件。

例如,我希望它只在字段为时返回username值,否则只是跳过记录。一些表示这一点的伪代码可能如下所示:activity_count>=1

if  '"activity_count":' >=1 grep -Po '"username": *\K"[^"]*"' jsonraw > jsonclean

我意识到这可能是一个更简单的选择,但由于 JSON 数据的格式错误和其他原因,jq我更愿意坚持使用。grep

样本数据:

[
{"id":"37da1db11b6b4977902baa286f88bf05","activity_count":0,"blocked":false,"coverPhoto":"cb861013bdcc4e5f9e2a93394a7b4309","followed":true,"human":true,"integration":false,"joined":"20190602125229","muted":false,"name":"AV8R","rss":false,"private":false,"profilePhoto":"511d4625df2442fc9b02ab4279c28f09","subscribed":false,"username":"APALMER66","verified":false,"verifiedComments":false,"badges":[0],"score":"1.4k","interactions":259},{"id":"525f9e87bb2d4f4184d12037050afc8d","activity_count":2,"blocked":false,"coverPhoto":"b0bbb4dec22f40d6a347dfb666ff0158","followed":true,"human":true,"integration":false,"joined":"20200627154134","muted":false,"name":"DeziRay","rss":false,"private":false,"profilePhoto":"86627047425844fcbf921e53fc71d106","subscribed":false,"username":"Deziray","verified":false,"verifiedComments":false,"badges":[0],"score":"4.7k","interactions":259},

预期输出:

Deziray

标签: jsonbashgrep

解决方案


首先(因为它更容易),一个jq答案:

jq -nr --stream '
fromstream(1|truncate_stream(inputs))
| select(.activity_count >= 1)
| .username
' <test.json

因为它在流模式下运行,所以它甚至能够处理截断的文档。


推荐阅读