bash之jq处理json
一、 核心基础:精准定位 (Selectors)
与 JSON 交互的起点,解决“数据在哪”的问题。
- **
.(Identity)**:最基础的过滤器,输出原始 JSON 且自动格式化(Pretty-print)。 - **
.field(Object Access)**:通过键名获取值。如果键名包含特殊字符(如横线),需使用引号:."user-name"。 - **
.parent.child(Chaining)**:通过点号链接,深度进入嵌套结构。 - **
.[](Array/Object Iterator)**:- 用于数组时:将数组拆解为一个个独立的元素流。
- 用于对象时:返回对象所有属性的值流(不含键名)。
- **
.[index](Index Access)**:获取数组特定位置元素,支持负数索引(如.[-1]获取末尾元素)。 - **
.[start:end](Slicing)**:对数组或字符串进行切片,遵循左闭右开原则。
假设有一个名为 data.json 的文件:
1 | { |
1 | # 漂亮打印 |
二、 数据重塑:构造与转换 (Construction)
经常需要将原始数据清洗并重新包装,输出给下一个微服务。从杂乱的原始数据中“提取、变形、再包装”,生成完全符合业务需求的新结构。
- **
{}(Object Construction)**:从现有数据中提取字段并重命名:{name: .user, id: .uuid}。 - **
[](Array Construction)**:将多个输出结果收集到一个数组中:[.id, .status]。 - **
|(Pipe)**:核心灵魂。将前一个过滤器的输出传给下一个,实现逻辑解耦。 - **
,(Comma)**:并行处理。同一个输入会经过多个过滤器,产生多条独立的输出。 - **
+,-,\*,/(Math & Merging)**:- 数字:进行常规算术运算。
- 对象:
obj1 + obj2用于合并对象(重复键以后者为准)。 - 数组:
arr1 + arr2用于连接数组。
假设有一个原始数据文件 server.json
1 | { |
1 | # {}对象构造,从复杂原始数据中提取几个关键字段,并起个别名 |
1 | # 数值运算 |
三、 高级逻辑:函数与过滤 (Functions & Logic)
精通 jq 的关键在于利用内置函数处理复杂业务逻辑。
- **
select(boolean_expression)**:数据过滤利器。例如select(.age > 18)只保留符合条件的元素。 - **
map(filter)**:针对数组中的每个元素应用过滤器,并返回处理后的新数组。 - **
keys&has("key")**:keys:以数组形式返回对象的所有键名。has("status"):检查对象是否包含特定键,返回布尔值。
- **
length**:通用长度计算。支持字符串长度、数组元素个数及对象键值对数量。 - **
if-then-else-end(Conditionals)**:if .status == 200 then "OK" else "Error" end。
- **
try-catch**:处理异常。在解析可能缺失字段或格式不统一的数据时,防止脚本崩溃。
四、 命令行超能力 (CLI Flags)
在 Bash 脚本中,参数决定了 jq 如何与外界交互。
-r(Raw Output):必记项。去掉输出字符串的双引号。在 Shell 脚本中给变量赋值时,这是必须选用的。- **
-c(Compact Output)**:将 JSON 压缩为一行。适合在大规模日志处理或 API 传输中使用,节省带宽和磁盘空间。 - **
-s(Slurp)**:将输入流中的多个独立 JSON 对象读入一个巨大的数组中,方便进行全局统计(如length或max)。 - **
-R(Raw Input)**:将非 JSON 的普通文本行读取为字符串。配合正则函数(test,match)可以将普通日志转化为结构化 JSON。 - **
--arg(Variable Injection)**:从外部 Bash 环境传入变量:jq --arg v "$VERSION" '.version = $v'。
五、 实战案例
- 多层级深度提取:
jq '.data.items[].metadata | {id: .uid, name: .name}'- 场景: 从 K8s API 返回的复杂对象中提取关键元数据。
- 复杂条件统计:
jq '[.[] | select(.price > 100)] | length'- 场景: 统计电商接口中价格超过阈值的商品总数。
- 动态修改配置:
jq '.database.host = "127.0.0.1" | .debug = true' config.json- 场景: 在 CI/CD 流水线中根据环境动态更新配置文件。
- **数据扁平化 (Flatten)**:
jq '[.projects[].tasks[]] | unique'- 场景: 将嵌套的项目任务列表拉平,并去除重复任务。
小贴士: 当你面对极其复杂的过滤器时,可以将其写入文件(如
logic.jq),然后使用jq -f logic.jq data.json执行。这能极大地提高代码的可读性和可维护性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 满杯是幸福 空杯是自由!
评论
