我有以下字符串:
{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}
,我需要得到"scheme version"的值,在这个例子中是1234。
我试过了
grep -Eo ""scheme_version":(w*)"
但是它返回
"scheme_version":1234
我怎样才能做到呢?我知道我可以添加sed调用,但我更喜欢使用单个grep。
您需要使用查看后面的断言,以便它不包含在匹配中:
grep -Po '(?<=scheme_version":)[0-9]+'
这可能适合您:
echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' |
sed -n 's/.*"scheme_version":([^}]*)}/1/p'
1234
对不起,它不是grep,所以如果你喜欢,忽略这个解决方案。
或者继续使用grep并添加:
grep -Eo ""scheme_version":(w*)"| cut -d: -f2
我建议您使用jq来完成这项工作。jq是一个命令行JSON处理器
$ cat tmp
{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}
$ cat tmp | jq .scheme_version
1234
作为SiegeX建议的正向后查找方法的替代方法,您可以使用K
转义序列将匹配起点直接重置为scheme_version":
之后。例如,
$ grep -Po 'scheme_version":K[0-9]+'
这将在匹配scheme_version":
后重新启动匹配过程,并且往往比正向后看的性能要好得多。在regexp101上比较两者表明,重置匹配开始方法需要37个步骤和1ms,而正面向后看方法需要194个步骤和21ms。
您可以自己比较regex101上的性能,您可以在PCRE文档中阅读有关重置匹配起点的更多信息。
为了避免使用grep
的PCRE特性,该特性在GNU grep
中可用,但在BSD版本中没有,另一种方法是使用ripgrep
,例如
$ rg -o 'scheme_version.?:(d+)' -r '$1' <file.json
1234
-r
捕获组索引(如$5
)和名称(如$foo
)。
另一个Python和json.tool
模块的例子,可以验证和漂亮打印:
$ python -mjson.tool file.json | rg -o 'scheme_version[^d]+(d+)' -r '$1'
1234
相关:grep可以只输出匹配的指定分组吗?
你可以这样做:
$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | awk -F ':' '{print $4}' | tr -d '}'
改进@potong的答案,它只能得到"scheme_version",您可以使用这个表达式:
$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | sed -n 's/.*"_id":["]*([^(",})]*)[",}].*/1/p'
scheme_version
$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | sed -n 's/.*"_rev":["]*([^(",})]*)[",}].*/1/p'
4-cad1842a7646b4497066e09c3788e724
$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | sed -n 's/.*"scheme_version":["]*([^(",})]*)[",}].*/1/p'
1234