使用 jq 高效递归处理 JSON 数据:去除空值、类型转换与字符串清理

使用 jq 高效递归处理 JSON 数据:去除空值、类型转换与字符串清理
最新回答
可爱的害羞鬼

2026-10-20 09:07:30

使用 jq 高效递归处理 JSON 数据的完整方案如下,包含空值移除、类型转换与字符串清理,并针对性能优化:

核心实现代码def walk(f): def w: if type == "object" then . as $in | reduce keys_unsorted[] as $key ( {}; . + { ($key): ($in[$key] | w) } ) | f elif type == "array" then map(w) | f else f end; w;walk( if type == "string" then (sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; "") | if . == "true" then true elif . == "false" then false else . end) elif type == "object" then with_entries( select(.value | IN("", null, [], {}) | not) | .key |= sub("^[[:space:]]+"; "") | .key |= sub("[[:space:]]+$"; "") | select(.key | IN("") | not) ) elif type == "array" then map(select(. | IN("", null, [], {}) | not)) else . end)分步功能解析
  1. 自定义 walk 函数优化

    使用 reduce keys_unsorted[] 替代 with_entries,避免排序开销,提升对象处理速度。

    递归处理子节点后统一应用过滤器 f,减少重复计算。

  2. 字符串处理逻辑

    清理空白:sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; "") 移除首尾空格。

    类型转换:将 "true"/"false" 转为布尔值,其他字符串保留原值。

  3. 对象处理逻辑

    过滤空值:select(.value | IN("", null, [], {}) | not) 移除值为空的键值对。

    清理键名:对键名执行与字符串值相同的空白清理。

    过滤空键:select(.key | IN("") | not) 移除键名为空的条目。

  4. 数组处理逻辑

    map(select(. | IN("", null, [], {}) | not)) 递归过滤数组中的空元素。

性能优化要点
  • 避免中间对象创建:通过 reduce 直接构建新对象,减少内存分配。
  • 减少管道操作:合并字符串处理步骤(空白清理与类型转换),降低 CPU 循环开销。
  • 使用 keys_unsorted:在无需键排序的场景下,比 keys 更快。
示例输入与输出

输入:

{ "key1": " value1 ", "key2": "", "key3": "true", "key4": "false", "key5": [], "key6": {}, "key7": null, "key8": { "nested_key": " nested_value ", "empty_object_key": {} }, "key9": [ "array_item_1", "", " array_item_2 ", [] ], " empty_key ": 123}

输出:

{ "key1": "value1", "key3": true, "key4": false, "key8": { "nested_key": "nested_value" }, "key9": [ "array_item_1", "array_item_2" ]}注意事项
  1. 版本兼容性:代码兼容 jq 1.6+,低版本可能需要调整语法。
  2. 内存限制:处理超大规模 JSON 时,考虑使用 jq --stream 分块处理。
  3. 错误处理:生产环境建议添加 try/catch 捕获异常(如非布尔字符串转换)。
  4. 可读性优化:可将复杂逻辑拆分为独立函数,例如:def trim: sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; "");def to_bool: if . == "true" then true elif . == "false" then false else . end;
总结

此方案通过优化递归遍历与数据处理逻辑,显著降低了 CPU 消耗,尤其适合处理嵌套层级深的 JSON 数据。实际使用时,建议先在小规模数据上验证结果,再逐步扩展至生产环境。