通过命令行传参指定字段路径 使用jq构建目标JSON输出文档
jq 按命令行传入路径提取字段问题
这是此前已获得优质解答的相关问题的后续问询。
示例输入JSON
[ { "x1": "abc123", "x2": "Larry", "attr": { "f1": "one", "f2": ["two", "2"], "f3": "three", "x1": "Never included in below examples as this is .attr.x1, not .x1" } }, { "x1": "xyz789", "x2": "Curly", "attr": { "f1": ["one", "111"], "f2": "two" } }, { "x1": "def456", "x2": "moe", "attr": { "f4": { "a": 1, "b": "two" } } } ]
核心需求
编写通用jq程序,支持通过命令行--args参数传入需要在输出中保留的字段路径:
- 输出结果自动移除所有非目标路径对应的字段
- 不存在的目标路径取值为null
运行示例1
执行命令:
jq -f program.jq test.json --args x1 attr.f1 attr.f3
预期输出:
[ { "x1": "abc123", "attr": { "f1": "one", "f3": "three" } }, { "x1": "xyz789", "attr": { "f1": ["one", "111"], "f3": null } }, { "x1": "def456", "attr": { "f1": null, "f3": null } } ]
运行示例2
执行命令:
jq -f program.jq test.json --args x1 x2 attr.f2 attr.f4
预期输出:
[ { "x1": "abc123", "x2": "Larry", "attr": { "f2": ["two", "2"], "f4": null } }, { "x1": "xyz789", "x2": "Curly", "attr": { "f2": "two", "f4": null } }, { "x1": "def456", "x2": "moe", "attr": { "f2": null, "f4": { "a": 1, "b": "two" } } } ]
规则说明
- 对参数传入语法无强制要求,若使用
--argsjson、其他路径指定方式、多命令拼接管道等方案更易实现,均可接受 - 不同层级的键名可重复,仅精确匹配完整路径的字段会被纳入输出,例如示例中
.attr.x1始终不会被保留,仅保留根级.x1字段 - 示例结构较为简单,实际业务中输入JSON最高可达5层左右嵌套,需支持任意深度的键值提取(例如路径
.attr.level2.level3.level4.mykey) - 实际输入规模覆盖范围较广:小到十余条记录、待提取字段少于20个的小文档,大到10万条记录、约100个待提取字段的大文档,性能需达到可用水平,无极致性能要求
- 补充说明:不排斥使用Jinja2等模板工具在运行时动态生成jq程序的方案,该类方案虽非最优但完全可接受。
已尝试方向
目前已尝试结合map、with_entries等函数编写多种实现逻辑,但始终无法适配「目标路径通过命令行参数传入」的需求,寻求可行的解决方案。
内容的提问来源于stack exchange,提问作者SteveT
相关产品推荐
相关产品推荐

