跳转至

jq JSON 命令行处理

一句话概述:jq 是命令行 JSON 处理工具,能解析、过滤、转换 JSON 数据,是处理 API 返回数据和配置文件的利器。

核心知识点

概念白话解释
jqJSON 处理器 = 命令行版 JSON 编辑器
Filter过滤器 = 提取/转换 JSON 的表达式
Pipe管道 = 用 \| 串联多个过滤器
.当前对象 = 代表输入的整个 JSON
.key取值 = 提取某个字段
.[]遍历 = 展开数组的每个元素

安装

# Linux
sudo apt install jq                                    # Ubuntu/Debian

# macOS
brew install jq                                        # Homebrew

# 验证
jq --version                                          # 查看版本

基础用法

# 格式化(美化打印)
echo '{"name":"T2D","samples":50}' | jq .              # 格式化输出
cat data.json | jq .                                   # 格式化文件内容

# 提取字段
echo '{"name":"T2D","samples":50}' | jq '.name'        # 输出: "T2D"
echo '{"name":"T2D","samples":50}' | jq '.samples'     # 输出: 50

# 去掉引号(原始值)
echo '{"name":"T2D"}' | jq -r '.name'                  # 输出: T2D(无引号)

# 嵌套取值
echo '{"project":{"name":"T2D","year":2026}}' | jq '.project.name'  # 输出: "T2D"

# 数组操作
echo '[1,2,3,4,5]' | jq '.[0]'                        # 第一个元素: 1
echo '[1,2,3,4,5]' | jq '.[-1]'                       # 最后一个: 5
echo '[1,2,3,4,5]' | jq '.[1:3]'                      # 切片: [2,3]
echo '[1,2,3,4,5]' | jq '.[]'                         # 展开所有元素
echo '[1,2,3,4,5]' | jq 'length'                      # 数组长度: 5

进阶用法

# === 过滤 ===
# 假设 samples.json 内容:
# [{"id":"S1","group":"T2D","shannon":3.2},
#  {"id":"S2","group":"Control","shannon":4.1},
#  {"id":"S3","group":"T2D","shannon":2.8}]

cat samples.json | jq '.[] | select(.group == "T2D")'  # 筛选 T2D 组
cat samples.json | jq '.[] | select(.shannon > 3.0)'   # Shannon > 3.0
cat samples.json | jq '[.[] | select(.group == "T2D")]' # 筛选后保持数组

# === 转换/构造 ===
cat samples.json | jq '.[] | {sample_id: .id, diversity: .shannon}'  # 重命名字段
cat samples.json | jq '[.[] | .shannon]'               # 提取所有 shannon 值为数组
cat samples.json | jq '[.[] | .shannon] | add/length'  # 计算平均值

# === 排序 ===
cat samples.json | jq 'sort_by(.shannon)'              # 按 shannon 升序
cat samples.json | jq 'sort_by(.shannon) | reverse'    # 降序

# === Map/Reduce ===
cat samples.json | jq 'map(.shannon)'                  # 提取所有 shannon: [3.2, 4.1, 2.8]
cat samples.json | jq 'map(.shannon) | add'            # 求和: 10.1
cat samples.json | jq 'map(.shannon) | min'            # 最小值: 2.8
cat samples.json | jq 'map(.shannon) | max'            # 最大值: 4.1

# === 条件表达式 ===
cat samples.json | jq '.[] | .id + ": " + (if .shannon > 3 then "高" else "低" end)'

# === 处理 API 返回 ===
curl -s https://api.github.com/repos/samtools/samtools/releases/latest \
  | jq '{tag: .tag_name, date: .published_at, url: .html_url}'  # 提取关键信息

# === 输出为 TSV/CSV ===
cat samples.json | jq -r '.[] | [.id, .group, .shannon] | @tsv'  # 转 TSV
cat samples.json | jq -r '.[] | [.id, .group, .shannon] | @csv'  # 转 CSV

# === 修改 JSON ===
cat config.json | jq '.threads = 8'                    # 修改字段值
cat config.json | jq '.threads = 8 | .memory = "16G"'  # 修改多个字段
cat config.json | jq '. + {"new_field": "value"}'      # 添加新字段
cat config.json | jq 'del(.old_field)'                 # 删除字段

实用场景

# 处理 Nextflow 流程日志
cat trace.json | jq '.[] | select(.status == "FAILED") | .name'  # 查找失败任务

# 解析 conda 环境
conda list --json | jq '.[] | select(.name | contains("bio"))'  # 查找 bio 相关包

# 处理 NCBI API
curl -s "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=T2D+microbiome&retmode=json" \
  | jq '.esearchresult.idlist'                         # 提取 PubMed ID 列表

常见报错

报错原因解决
parse error输入不是合法 JSON检查 JSON 格式(逗号/引号)
null字段不存在检查字段名,用 ? 避免报错:.key?
Cannot iterate over null对 null 做遍历加判空:(.field // []) | .[]
中文乱码编码问题确保终端支持 UTF-8

速查表

# 基本语法
jq 'FILTER' file.json                                 # 处理文件
echo 'JSON' | jq 'FILTER'                             # 处理管道输入
jq -r                                                 # 原始输出(无引号)
jq -c                                                 # 紧凑输出(单行)
jq -e                                                 # 结果为 false/null 时返回非0

# 核心过滤器
# .            → 当前对象
# .key         → 取字段
# .key1.key2   → 嵌套取值
# .[]          → 遍历数组
# .[N]         → 取第N个
# .[N:M]       → 切片
# length       → 长度
# keys         → 所有键名
# values       → 所有值
# type         → 类型

# 常用函数
# select(cond)    → 过滤
# map(expr)       → 映射
# sort_by(.key)   → 排序
# group_by(.key)  → 分组
# unique_by(.key) → 去重
# add             → 求和/合并
# min / max       → 最值
# @tsv / @csv     → 格式化输出