用途
该技能面向 shell 管道中的 JSON 处理:编写、解释和调试 jq 程序,用于过滤、重塑、聚合、合并与转换 JSON。其基本立场是:在 shell 管道处理 JSON 时优先使用 jq,而不是临时写脚本;假定用户已掌握标准 jq 语法,技能重点放在那些会静默产生错误输出的常见错误上。
主要能力
版本检查与降级写法
使用较新版本的内置函数前,先运行 jq --version。发行版和操作系统自带的构建往往版本滞后。当某个内置函数报 <name>/<arity> is not defined 时,资料给出以下替代写法:
- 需要 1.7:pick(.a, .b.c);替代写法: . as $in | reduce path(.a, .b.c) as $p (null; setpath($p; $in | getpath($p)))
- 需要 1.7:abs;替代写法:if . < 0 then -. else . end
- 需要 1.7:不带 else 的 if;替代写法:补上 else . end
- 需要 1.8:trim、ltrim、rtrim;替代写法分别为 gsub("^\s+|\s+$"; "")、sub("^\s+"; "")、sub("\s+$"; "")
- 需要 1.8:add(f);替代写法:[f] | add
- 需要 1.8:skip(n; f);替代写法:[f][n:][]
- 需要 1.8:@urid;没有 jq 内的替代写法,需在 jq 之外解码
另外,leaf_paths 在 1.7 中被移除,所有版本都应改用 paths(scalars)。gh --jq 运行的是内置的 jq 实现,而非已安装的 jq,因此上述版本清单不适用于它。
常见陷阱
- shell 值:通过 --arg name "$v"(始终为字符串)或 --argjson name "$v"(数字、布尔、JSON)传入,切勿把 shell 变量拼接进程序。jq 中所有字符串都排在所有数字之上,因此用 --arg n 1 时,$n > 3 会静默为真。
- 默认值:.x // d 除了替换 null 还会替换 false,所以 .enabled // true 会把显式 false 变成 true。当 false 有意义时,改用 if .enabled == null then true else .enabled end。
- 展平:flatten(1) 去掉一层并保留标量;[.[][]] 遇到任意标量元素会报错;裸 flatten 去掉所有层级。
- CSV 与 TSV:@csv 和 @tsv 只接受标量数组,嵌套值需先用 tojson 转换。使用 -r 以免整行被再次加引号。
- shell 消费:交给其他命令的字符串用 -r,每行一个 JSON 值用 -c,在条件判断中用 -e(最后一个输出为 false 或 null 时退出码 1,无输出时退出码 4)。
- 多文档:-s 会把所有输入载入内存中的一个数组。对大输入或流式输入,改用 -n 配合 inputs,或 reduce inputs as $x。
- 大整数:超过 2^53 的整数在算术中会丢失精度,在 1.7 之前的 jq 中输出时也会如此。ID 应保留为字符串。
使用方式
原地编辑文件
jq '...' f.json > f.json 会在 jq 读取前就截断 f.json。应写入临时文件,确认其中恰好包含一个预期类型的 JSON 值,再替换原文件:
jq '.version = "2.0"' package.json > package.json.tmp && jq -se 'length == 1 and (.[0] | type == "object")' package.json.tmp > /dev/null && mv package.json.tmp package.json
将 "object" 设为文件应持有的类型。任何步骤失败,就删除 package.json.tmp 并保持原文件不变。该校验会拒绝输出流(多余的 .[])、无输出或类型错误(多余的 .version)的过滤器,而这些情况 jq empty 都会接受。
参考资料
- 内置函数:在需要某个内置函数的确切签名、正则标志、日期格式或格式字符串时阅读。
- 高级模式:在使用 reduce、foreach、用 --stream 流式处理大文件、递归遍历、跨文件 join 或自定义函数时阅读。
在使用某一步骤开始时,从该技能目录读取相应链接文件。若读取失败,停止该步骤并报告确切路径。
适用场景与限制
适用于在 shell 管道或命令行中对 JSON 做解析、筛选、转换、查询、聚合、合并与格式转换,以及安全地原地修改 JSON 文件。资料未提供该技能在其他环境(如非命令行程序、图形界面)中的用法,也未说明安装方式、收费情况或性能数据。