如何用正则在任意深度修改JSON属性值?修复Schema的$ref引用
批量修复JSON Schema中$ref的缺失后缀问题
问题背景
有一批命名为*object_name*.json的JSON Schema文件,其中的$ref属性值缺少.json后缀(例如TypeDefinitions#/extensions需修正为TypeDefinitions.json#/extensions),导致校验工具无法解析引用。手动修改效率极低,尝试用jq批量处理时遇到报错。
尝试的错误命令
jq 'walk(if type == "object" and has("$ref") then .["$ref"] = (. | sub("(?<a>[^#]*)(?<b>#.*)*$"; "\(.a).json\(.b + """)")) else . end)' FubarAgent.json
报错信息
jq: error (at FubarAgent.json:28): object ({"$ref":"Ty...) cannot be matched, as it is not a string
错误原因
报错核心是代码中错误地对包含$ref的整个对象执行字符串替换操作(. | sub(...)中的.指向当前对象),而非针对$ref对应的字符串值处理。
修复后的jq命令
单文件处理
jq 'walk(if type == "object" and has("$ref") then ."$ref" |= sub("^([^#]+)(#.*)?$"; "\1.json\2") else . end)' FubarAgent.json
关键逻辑解释
walk(...):递归遍历JSON结构的所有层级type == "object" and has("$ref"):精准定位包含$ref属性的对象."$ref" |= sub(...):使用|=更新操作符,直接对$ref的字符串值执行替换,无需额外取值赋值步骤- 正则表达式
^([^#]+)(#.*)?$:^([^#]+):匹配#符号之前的文件名部分(#.*)?:可选匹配#及后续的JSON Pointer路径(无路径则为空)
- 替换模板
\1.json\2:在文件名后追加.json,完整保留原有的#路径部分
批量处理所有JSON文件(Bash环境)
为避免直接覆盖原文件导致数据损坏,先输出到临时文件,确认无误后再替换原文件:
for file in *.json; do jq 'walk(if type == "object" and has("$ref") then ."$ref" |= sub("^([^#]+)(#.*)?$"; "\1.json\2") else . end)' "$file" > "$file.tmp" && mv "$file.tmp" "$file" done
内容的提问来源于stack exchange,提问作者Mr. Lance E Sloan
相关产品推荐
相关产品推荐

