如何使用jq按路由白名单过滤OpenAPI规范且保留其他顶级字段
jq过滤OpenAPI路径解决方案
报错原因
原代码第一行.paths直接将根上下文替换为了paths字段的值,既丢失了其他顶级字段,若输入中paths为null时就会触发「Cannot iterate over null」错误。
实现需求的完整方案
核心逻辑
使用jq的更新运算符|=仅修改paths字段,其余所有原始结构完全保留;白名单单独定义,新增/删除路由只需修改白名单列表即可。
1. 白名单内置在脚本中(适合固定筛选规则)
直接将需要保留的路由写在脚本开头,维护时只需修改数组内容:
# 需保留的路由列表,后续新增路由直接往数组中添加即可 ["/pets"] as $whitelist # 仅过滤paths字段,其余所有字段原封不动保留 | .paths |= with_entries( # jq 1.6+ 可用IN函数简化匹配逻辑 select( .key | IN($whitelist[]) ) # 低版本jq可替换为下面的写法 # select( .key as $k | any($whitelist[]; . == $k) ) )
运行命令:
jq -f filter.jq your_openapi.json
2. 白名单从外部传入(适合动态调整规则)
无需修改jq逻辑,直接通过参数传入白名单,更适合多场景复用:
jq --argjson whitelist '["/pets", "/route2", "/route3"]' \ '.paths |= with_entries( select( .key | IN($whitelist[]) ) )' \ your_openapi.json
如果路由数量多,还可以单独维护一个路由列表文件whitelist.txt(每行一个路由),通过shell动态生成数组传入:
# 从txt文件读取路由生成白名单参数 whitelist_param=$(jq -R -s -c 'split("\n") | map(select(length > 0))' whitelist.txt) # 执行过滤 jq --argjson whitelist "$whitelist_param" '.paths |= with_entries( select( .key | IN($whitelist[]) ) )' your_openapi.json
输出效果
针对你提供的示例JSON,运行后输出结果如下,所有原始结构保留,仅过滤了paths中的路由:
{ "swagger": "2.0", "info": {}, "host": "petstore.swagger.io", "basePath": "/api", "schemes": [], "consumes": [], "produces": [], "paths": { "/pets": {} }, "definitions": {} }
内容的提问来源于stack exchange,提问作者karlos
相关产品推荐
相关产品推荐

