JQ创建嵌套对象遇问题,请求技术协助
修复JQ函数实现键值对转嵌套结构化JSON的问题
问题背景
需要实现一个JQ函数,将--arg传入的键值对转换为符合以下规则的结构化JSON:
- 键包含英文句点时,拆分生成嵌套对象
- 值包含英文逗号时,拆分为数组,同时自动识别值的类型(数字、布尔、null)
当前代码仅最后一个参数被正确处理,其余参数未完成类型转换,且保留了未拆分的原始键(如sea.creatures)。
问题根源
args2json函数的reduce逻辑错误- 初始累积器使用数组
[]而非空对象{},不符合目标结构要求 - 每次循环都合并原始参数集合
$params,导致未处理的原始键值对被保留 - 变量名拼写错误:
$entrties应为$entry - 多余的
del(.key) | del(.value)操作,setpath已生成正确结构,无需额外删除
- 初始累积器使用数组
cast_arg函数类型转换不完整- 当值按逗号拆分后长度为1时,直接返回原始字符串,未递归调用
cast_arg转换类型,导致数字、布尔值等无法被识别
- 当值按逗号拆分后长度为1时,直接返回原始字符串,未递归调用
修复后的完整代码
# Cast some text into the most likely value and appropriate data type def cast_arg: . as $val | if $val == "null" then null elif $val == "true" then true elif $val == "false" then false else ( $val | try tonumber catch ($val | split(",") as $segments | if ($segments|length) == 0 then null elif ($segments|length) == 1 then $segments[0] | cast_arg # 递归转换单个值 else ($segments|map(cast_arg)) end ) ) end; # Take the --arg foo.bar baz,bang,qux into {foo: {bar: [baz, bang, qux]}} def args2json: to_entries # 转换为键值对数组 | reduce .[] as $entry ({}; # 从空对象开始累积结果 . | setpath($entry.key | split("."); $entry.value | cast_arg) ); # 直接输出转换结果,若需外层params键可改为 .params=($ARGS.named | args2json) $ARGS.named | args2json
修复说明
cast_arg函数:当拆分后仅单个值时,递归调用cast_arg确保数字、布尔值、null能被正确转换args2json函数:- 使用空对象作为reduce初始值,正确累积嵌套结构
- 每次循环仅将当前处理后的键值对合并到结果中,避免保留原始未处理的键
- 修正变量名拼写错误,移除冗余的删除和合并操作
- 输出逻辑:直接输出转换后的JSON结构,若需要外层
params键可恢复.params=...写法
测试验证
执行原命令:
jq --null-input \ --arg count 5 \ --arg name john \ --arg enabled false \ --arg shouldbenull null \ --arg mamals pig,cat,dog \ --arg sea.creatures 'shark,crab,654,squid' \ --from-file ./jq/modifiers/args2json.jq
将得到预期输出:
{ "count": 5, "name": "john", "enabled": false, "shouldbenull": null, "mamals": [ "pig", "cat", "dog" ], "sea": { "creatures": [ "shark", "crab", 654, "squid" ] } }
内容的提问来源于stack exchange,提问作者J H
相关产品推荐
相关产品推荐

