寻求JQ动态过滤器:实现与Bash函数一致的JSON全量键值输出
用JQ实现兼容原有Bash JSON解析函数的全量键值对输出(适配大JSON)
核心JQ过滤器(流式处理,低内存占用)
针对10^8字符级的超大JSON文件,使用jq的tostream特性实现流式遍历,避免加载整个文件到内存,同时生成与原有Bash函数完全一致的键值对格式:
tostream | select(length == 2) # 处理完整路径:对象键用`.`前缀,数组索引用`[n]`格式 | (.[0] | map( if type == "number" then "[" + tostring + "]" else "." + tostring end ) | join("") | ltrimstr(".")) as $full_path # 处理值:字符串加双引号,其他类型直接转字符串(可根据原有Bash函数调整) | (.[1] | if type == "string" then "\"" + . + "\"" else tostring end ) as $value # 拼接成键值对格式 | "\($full_path)=\($value)"
过滤器详解
- 流式处理:
tostream将JSON分解为路径-值的流条目,仅处理长度为2的有效键值对(跳过结构结束标记),内存占用极低,完美适配超大文件场景。 - 路径格式化:
- 数组索引(数字类型路径节点)转换为
[n]格式 - 对象键(字符串类型路径节点)转换为
.key格式 - 拼接后去除开头的
.,得到如user.addresses[0].street的完整路径
- 数组索引(数字类型路径节点)转换为
- 值格式化:
- 字符串类型值添加双引号,与Bash解析函数的字符串输出对齐
- 布尔值、数字、
null直接转换为字符串,保持类型一致性
适配原有Bash函数的调整点
如果原有Bash函数的输出格式有特殊要求,可针对性修改过滤器:
- 路径分隔符:若不用
.分隔对象键,比如用_,将路径处理部分的"." + tostring改为"_" + tostring即可 - 字符串转义:若原有函数对含特殊字符的字符串做shell转义,将值处理部分的
"\"" + . + "\""替换为@sh(生成shell兼容的转义字符串) - 空值处理:若原有函数对
null输出空字符串,将else tostring改为else if . == null then "" else tostring end
使用示例
处理超大JSON文件large_data.json,直接执行:
jq -r 'tostream | select(length == 2) | (.[0] | map(if type == "number" then "[" + tostring + "]" else "." + tostring end) | join("") | ltrimstr(".")) as $full_path | (.[1] | if type == "string" then "\"" + . + "\"" else tostring end) as $value | "\($full_path)=\($value)"' large_data.json
将原有脚本中调用Bash解析函数的逻辑替换为上述命令,即可无缝兼容所有依赖脚本,同时彻底解决大JSON的性能瓶颈。
内容的提问来源于stack exchange,提问作者nbanba
相关产品推荐
相关产品推荐

