grep正则表达式的一些帮助

时间:2015-09-16 22:31:36

标签: json regex bash grep capture

我对“正常”RegEx和grep理解的语法之间的区别感到有些不满。我想请求您提供以下帮助。

我将此文本放在“deployments.txt”文件中:

{"data":[{"id":"local$1cb66e07-2e75-40c4-9ea7-cdda2e62a7e9","name":"some-other-app","servers":["f150ee04-6250-4b97-a2d7-f6511186b6b4"],"applications":["local$1552a8d2-4c9d-4256-b635-a15c4187f4ee"],"lastModified":"Mon, 14 Sep 2015 11:34:52.474 CEST","reconciled":false,"status":"DEPLOYED","href":"https://host123:7777/mmc-3.6.1/api/deployments/local$1cb66e07-2e75-40c4-9ea7-cdda2e62a7e9","clusterIds":[],"clusterNames":[]},{"id":"local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b","name":"interesting-app","servers":["f150ee04-6250-4b97-a2d7-f6511186b6b4"],"applications":["local$87bc69d6-1b92-4e3a-a0f2-724c5d37aeaf"],"lastModified":"Mon, 14 Sep 2015 22:43:15.440 CEST","reconciled":false,"status":"DEPLOYED","href":"https://host123:7777/mmc-3.6.1/api/deployments/local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b","clusterIds":[],"clusterNames":[]}],"total":2}

现在我对此感兴趣:

"id":"local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b","name":"interesting-app"

或者实际上只是文本"name":"interesting-app"

之前的干净ID

“正常”正则表达式为:.*"id":"(.*?)","name":"interesting-app"在捕获组中生成local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b

但那些捕捉小组显然在grep中的工作方式不同,现在已经知道了,并且此后一直在反对这一点。

所以我现在得到了这个grep:

grep -Po '(?<="id":").*?(?=","name":"interesting-app)' deployments.txt

但是抓取太多,它从找到的第一个"id":"开始,然后在找到","name":"interesting-app后停止。

那我怎样才能得到我想要的结果呢?我想要紧接在"name":"interesting-app"之前的干净id值。

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

jq是一个更好的解析shell中JSON的工具。它有一个相当强大的微型查询语言,用于选择甚至修改JSON数据。

带上一只雄鹅:

$ jq -r '.data | map(select(.name == "interesting-app")) | .[].id' deployments.txt
local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b

为了解释这是如何工作的,首先让我们看看所有id的简单查询:

$ jq -r '.data[].id' deployments.txt
local$1cb66e07-2e75-40c4-9ea7-cdda2e62a7e9
local$6b5fabb5-3e7e-4d16-9664-14977e3b1a7b

这将选择data密钥,然后[]选择所有数组元素,然后.id从每个数组条目中获取id密钥。

我的原始查询会在混合中添加select过滤条件,仅选择name "interesting-app"的{​​{1}}条目。事实证明,jq允许你将所谓的&#34;过滤器&#34;链接在一起。使用类似UNIX的管道。

您可以阅读jq manual以获取jq可以执行的所有操作的完整描述。

答案 1 :(得分:0)

使用这个简单的正则表达式

String patt="(\\.id.*interesting-app\\.)";

希望这有帮助

答案 2 :(得分:0)

这对你来说足够通用吗?

grep -Po '(?<="id":")[^"]*(?=","name":"interesting-app")' deployments.txt

。*?的问题在于它匹配第一个&#34; id&#34;:和最后一个&#34;之间的所有内容。名称&#34;:&#34;有趣应用内&#34;