如何用jq过滤值为0的PRI/SEC字段并格式化输出?
纯jq实现忽略值为"0"的PRI/SEC字段
当然可以用纯jq来搞定这个需求,完全不用依赖bash或awk。这里给你两种实用的思路,一步步拆解给你看:
方案一:先构建全量对象再过滤
先按需求生成包含所有目标字段的对象,再过滤掉值为"0"的键值对,最后格式化成你要的字符串样式:
jq -r '.[] | {PLATFORM: .platform, ID: .id, PRI: .pri, SEC: .sec} | with_entries(select(.value != "0")) | to_entries | map("\(.key):\(.value)") | join(", ")' test.json
命令拆解:
.[]:遍历输入数组里的每个对象{PLATFORM: .platform, ID: .id, PRI: .pri, SEC: .sec}:先按要求重命名字段,生成包含所有目标字段的临时对象with_entries(select(.value != "0")):过滤掉对象中值等于"0"的键值对to_entries:把对象转换成键值对数组(比如[{"key":"PLATFORM","value":"p1"}, ...])map("\(.key):\(.value)"):把每个键值对转成"KEY:VALUE"格式的字符串join(", "):用,把所有字符串拼接成一行
运行后输出完全符合你的期望:
PLATFORM:p1, ID:5, SEC:20 PLATFORM:p2, ID:6, PRI:10
方案二:按需构建对象(更高效)
如果不想先创建全量对象再过滤,也可以直接在构建对象时跳过值为"0"的字段,用条件判断实现:
jq -r '.[] | (if .pri != "0" then {PRI: .pri} else {} end) + (if .sec != "0" then {SEC: .sec} else {} end) + {PLATFORM: .platform, ID: .id} | to_entries | map("\(.key):\(.value)") | join(", ")' test.json
命令拆解:
- 用
if...then...else...end分别判断pri和sec的值,非"0"时生成对应键值对,否则生成空对象 - 用
+把这些对象和必选的PLATFORM、ID字段合并成新对象 - 后续的
to_entries、map、join步骤和方案一一致,负责格式化输出
这个方案的优势是不用先创建全量对象再过滤,处理大数据量时效率会更高。
内容的提问来源于stack exchange,提问作者user9252257
相关产品推荐
相关产品推荐

