← 中文资源

简体中文版本

JQ 命令行 JSON 变换管道

用 jq 过滤器变换 JSON:select 筛选降级服务、对象重塑输出统计、group_by 分区汇总、@csv 导出行,管道层层组合。

阅读英文原文

示例说明

curl 拿回来的 JSON 在 shell 里没有结构化处理能力——jq 补上这块拼图:过滤器是一门小型函数式语言,select 过滤、map 映射、add 聚合、group_by 分组。字符串插值语法把字段嵌进输出模板;-r 去掉外层引号让文本可读。它天然理解管道:curl | jq | xargs 组成无脚本的数据流水线。

技术要点

  • select 与 map 是过滤与映射原语
  • 字符串插值组装输出模板
  • @csv 与 @tsv 输出表格行

代码解读

第一个过滤器找出健康数小于副本数的服务并按模板输出降级报告;第二个用对象字面量一次性算出三个聚合值;group_by 按区域聚类后逐组输出汇总行。sort_by 负号表达降序,切片取前二。最后的 @csv 把数组转为转义后的 CSV 字段行写入文件。

使用建议

jq 的高频坑是数组与对象上下文混淆——.[] 展开数组逐项处理。大文件流式处理用 jq -c 配合逐行输入。复杂逻辑抽到 .jq 文件用 -f 引入。

代码示例

#!/usr/bin/env bash
set -euo pipefail

# 输入:带元数据的部署状态 JSON
readonly SAMPLE='[
  {"service": "api", "replicas": 3, "healthy": 3, "region": "eu"},
  {"service": "billing", "replicas": 4, "healthy": 2, "region": "eu"},
  {"service": "search", "replicas": 2, "healthy": 2, "region": "na"}
]'

# 字段选择与对象重塑:输出紧凑的行式报告
echo "$SAMPLE" | jq -r '.[]
  | select(.healthy < .replicas)
  | "\(.service) degraded: \(.healthy)/\(.replicas) in \(.region)"'

# 聚合统计:全部副本与亚健康服务数
echo "$SAMPLE" | jq '{
  total_replicas: (map(.replicas) | add),
  degraded: (map(select(.healthy < .replicas)) | length),
  regions: (map(.region) | unique)
}'

# 按区域分组汇总
echo "$SAMPLE" | jq -r 'group_by(.region)[]
  | "\(.[0].region): \(length) 个服务, 共 \(map(.replicas) | add) 副本"'

# 管道组合:先过滤再排序再取字段
echo "$SAMPLE" | jq -r 'sort_by(-(.replicas)) | .[:2] | .[].service'

# 从文件批量提取并输出 CSV 行
echo "$SAMPLE" | jq -r '.[]
  | [.service, (.replicas|tostring), (.healthy|tostring)] | @csv' \
  > status.csv
echo "written: $(wc -l < status.csv) rows"