如何在jq中通过try catch处理带.json后缀的键值对
需求描述
我有一个JSON对象,其中部分键名以.json结尾,示例如下:
{ "a.json": "...", .... }
上述示例中的"..."既可以是能被fromjson解码的字符串,也可以是其他内容。需要编写jq过滤器实现以下逻辑:
- 若值为可解析的JSON字符串,则将其替换为
fromjson解析后的结果,例如"{}"会转为{},处理后结果如下:
{ "a.json": {}, .... }
- 若值无法被解析,则移除键名的
.json后缀,例如值为"shh"时,处理后结果如下:
{ "a": "shh", .... }
所有以.json结尾的键都需按此规则处理,其余键值对保持不变。
我尝试了以下代码,该代码能正确处理值,但无法在catch块中修改键名:
with_entries( select(.key|test("\.json$")) as $root | $root.value = $root.value as $sub | ($sub|try fromjson catch $sub) )
解决方案
使用with_entries结合分支判断,先尝试解析值,再根据解析结果分别处理键和值:
with_entries( if .key | test("\\.json$") then .value as $v | ($v | try fromjson) as $parsed | if $parsed then .value = $parsed else .key = (.key | rtrimstr(".json")) end else . end )
代码说明
- 首先通过
test("\\.json$")筛选出键名以.json结尾的条目,其余条目直接保留 - 将原始值存入变量
$v,尝试用fromjson解析得到$parsed:解析成功时$parsed为解析后的JSON值,失败时$parsed为null - 根据解析结果分支处理:
- 解析成功:仅更新值为解析后的结果,键名保持不变
- 解析失败:用
rtrimstr(".json")移除键名的后缀,值保留原始内容
内容的提问来源于stack exchange,提问作者Tamás Horváth
相关产品推荐
相关产品推荐

