如何在JQ中安全处理可为Null的字段(清除换行与制表符)
问题
给定如下JSON数据:
[ { "alert_timestamp": "2024-10-23T08:49:08Z", "odin_timestamp": "2024-10-23T08:50:10Z", "alert_url": null, "comments": null, "owner": null, "updated_date": null, "clear_timestamp": "2024-10-23T09:27:39Z", "outage_duration_in_minutes": 38.52, "published_on": "DEFAULT", "atr_exec_id": null, "atr_status": null } ]
需求:当comments、alert_message等字段不为null时,去除字段内容中的换行符(\r\n)与制表符(\t);若字段为null则保留null。
尝试过两种写法均报错:
- 写法一:
map(.comments? |= (gsub("\r\n"; "") | gsub("\t"; ""))) | map(.alert_message? |= (gsub("\r\n"; "") | gsub("\t"; "")))
报错:
jq: error (at 16.json:338): null (null) cannot be matched, as it is not a string
- 写法二:
map((.comments // "") |= (gsub("\r\n"; "") | gsub("\t"; ""))) | map((.alert_message // "") |= (gsub("\r\n"; "") | gsub("\t"; "")))
报错:
jq: error (at 16.json:338): Invalid path expression with result ""
需要无需if/else分支判断的简洁解决方法。
解决方案
可以利用jq的strings过滤器结合//回退运算符实现,无需显式分支判断:
map( .comments |= (strings | gsub("\r\n|\t"; "") // .) | .alert_message |= (strings | gsub("\r\n|\t"; "") // .) )
原理说明
strings:仅保留字符串类型的值,非字符串(如null、数字等)会被过滤为nullgsub("\r\n|\t"; ""):通过正则表达式一次性替换所有换行符和制表符,比两次调用gsub更简洁// .:当strings过滤后得到null时,回退使用原始字段值,即保留null
如果需要批量处理所有对象中的字符串字段,还可以用walk函数简化:
walk( if type == "object" then with_entries( .value |= (strings | gsub("\r\n|\t"; "") // .) ) else . end )
这个写法会自动遍历所有对象字段,对其中的字符串执行替换操作,无需逐个指定字段名。
内容的提问来源于stack exchange,提问作者Christian Bongiorno
相关产品推荐
相关产品推荐

