news 2026/7/6 11:43:38

jq 1.6 实战:5个Shell脚本JSON处理场景与完整代码示例

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
jq 1.6 实战:5个Shell脚本JSON处理场景与完整代码示例

jq 1.6 实战:5个Shell脚本JSON处理场景与完整代码示例

JSON已经成为现代数据交换的事实标准,从API响应到配置文件,无处不在。对于开发者来说,能够高效处理JSON数据是一项必备技能。而jq作为命令行下的JSON处理神器,其强大功能和灵活性令人惊叹。本文将带你深入jq 1.6的实战应用,通过5个典型场景的完整Shell脚本示例,展示如何用jq解决实际问题。

1. API响应解析与数据提取

现代Web开发中,与API交互是家常便饭。假设我们有一个返回用户列表的API,响应如下:

{ "status": "success", "data": { "users": [ { "id": 101, "name": "张三", "email": "zhangsan@example.com", "active": true, "roles": ["admin", "editor"] }, { "id": 102, "name": "李四", "email": "lisi@example.com", "active": false, "roles": ["viewer"] } ], "total": 2 } }

需求:提取所有活跃用户的姓名和邮箱,并以CSV格式输出。

#!/bin/bash # 模拟API响应数据 api_response='{ "status": "success", "data": { "users": [ { "id": 101, "name": "张三", "email": "zhangsan@example.com", "active": true, "roles": ["admin", "editor"] }, { "id": 102, "name": "李四", "email": "lisi@example.com", "active": false, "roles": ["viewer"] } ], "total": 2 } }' # 使用jq处理并输出CSV echo "$api_response" | jq -r ' .data.users[] | select(.active == true) | [.name, .email] | @csv '

输出结果

"张三","zhangsan@example.com"

关键jq技巧

  • select()函数用于条件过滤
  • []展开数组
  • @csv格式化输出为CSV
  • -r选项输出原始字符串(去掉JSON引号)

2. 配置文件动态修改

开发中经常需要修改JSON格式的配置文件。假设我们有一个应用配置文件:

{ "app": { "name": "MyApp", "version": "1.0.0", "settings": { "debug": false, "logLevel": "info", "maxConnections": 10 } } }

需求:编写脚本将debug模式开启,并将maxConnections增加到20。

#!/bin/bash # 原始配置文件 config_file='config.json' echo '{ "app": { "name": "MyApp", "version": "1.0.0", "settings": { "debug": false, "logLevel": "info", "maxConnections": 10 } } }' > "$config_file" # 使用jq修改配置 jq '.app.settings.debug = true | .app.settings.maxConnections = 20' "$config_file" > tmp.json && mv tmp.json "$config_file" # 显示修改后的配置 echo "修改后的配置文件内容:" cat "$config_file"

修改后的配置文件

{ "app": { "name": "MyApp", "version": "1.0.0", "settings": { "debug": true, "logLevel": "info", "maxConnections": 20 } } }

关键jq技巧

  • 使用.操作符导航JSON结构
  • 使用|管道组合多个修改操作
  • 修改后输出到临时文件再替换原文件

3. 复杂JSON数据统计与分析

假设我们有一组销售数据:

[ { "date": "2023-01-01", "product": "A", "quantity": 10, "price": 99.99, "region": "North" }, { "date": "2023-01-02", "product": "B", "quantity": 5, "price": 199.99, "region": "South" }, { "date": "2023-01-03", "product": "A", "quantity": 8, "price": 99.99, "region": "North" } ]

需求:计算每种产品的总销售额和平均每单数量。

#!/bin/bash # 销售数据 sales_data='[ { "date": "2023-01-01", "product": "A", "quantity": 10, "price": 99.99, "region": "North" }, { "date": "2023-01-02", "product": "B", "quantity": 5, "price": 199.99, "region": "South" }, { "date": "2023-01-03", "product": "A", "quantity": 8, "price": 99.99, "region": "North" } ]' # 使用jq进行数据分析 echo "$sales_data" | jq ' group_by(.product) | map({ product: .[0].product, totalSales: (map(.quantity * .price) | add), averageQuantity: (map(.quantity) | add / length), transactionCount: length }) '

输出结果

[ { "product": "A", "totalSales": 1799.82, "averageQuantity": 9, "transactionCount": 2 }, { "product": "B", "totalSales": 999.95, "averageQuantity": 5, "transactionCount": 1 } ]

关键jq技巧

  • group_by()按字段分组
  • map()对数组元素进行转换
  • 数学计算直接在jq中完成
  • add函数计算数组总和

4. 日志文件过滤与转换

假设我们有如下结构的日志条目:

{"timestamp": "2023-06-15T10:00:00Z", "level": "INFO", "message": "User logged in", "user": "user1"} {"timestamp": "2023-06-15T10:01:00Z", "level": "ERROR", "message": "Failed to connect to DB", "error": "Connection timeout"} {"timestamp": "2023-06-15T10:02:00Z", "level": "WARN", "message": "High memory usage", "memory": "85%"}

需求:提取所有ERROR级别的日志,并转换为更简洁的格式。

#!/bin/bash # 日志数据 log_entries=' {"timestamp": "2023-06-15T10:00:00Z", "level": "INFO", "message": "User logged in", "user": "user1"} {"timestamp": "2023-06-15T10:01:00Z", "level": "ERROR", "message": "Failed to connect to DB", "error": "Connection timeout"} {"timestamp": "2023-06-15T10:02:00Z", "level": "WARN", "message": "High memory usage", "memory": "85%"} ' # 使用jq处理日志 echo "$log_entries" | jq -c ' select(.level == "ERROR") | { time: .timestamp, msg: .message, detail: (.error // .memory // .user // "No additional details") } '

输出结果

{"time":"2023-06-15T10:01:00Z","msg":"Failed to connect to DB","detail":"Connection timeout"}

关键jq技巧

  • -c紧凑输出
  • //操作符提供默认值
  • 条件选择特定日志级别
  • 重构JSON结构

5. 多文件数据合并与处理

场景:我们有两个JSON文件,需要合并并根据某些条件处理。

users.json:

[ {"id": 1, "name": "Alice", "department": "Engineering"}, {"id": 2, "name": "Bob", "department": "Marketing"} ]

salaries.json:

[ {"userId": 1, "salary": 80000}, {"userId": 2, "salary": 75000} ]

需求:合并两个文件,计算每个部门的平均薪资。

#!/bin/bash # 创建示例文件 echo '[ {"id": 1, "name": "Alice", "department": "Engineering"}, {"id": 2, "name": "Bob", "department": "Marketing"} ]' > users.json echo '[ {"userId": 1, "salary": 80000}, {"userId": 2, "salary": 75000} ]' > salaries.json # 使用jq合并处理 jq -n ' # 加载第一个文件 input as $users | # 加载第二个文件 input as $salaries | # 合并数据 [ $users[] as $user | $salaries[] as $salary | select($user.id == $salary.userId) | { name: $user.name, department: $user.department, salary: $salary.salary } ] | # 按部门分组计算平均薪资 group_by(.department) | map({ department: .[0].department, avgSalary: (map(.salary) | add / length), employeeCount: length }) ' users.json salaries.json

输出结果

[ { "department": "Engineering", "avgSalary": 80000, "employeeCount": 1 }, { "department": "Marketing", "avgSalary": 75000, "employeeCount": 1 } ]

关键jq技巧

  • input加载多个文件
  • 复杂的数据关联处理
  • 多步骤数据处理管道
  • group_by和统计计算

jq高级技巧与最佳实践

通过以上5个实战场景,我们已经领略了jq的强大功能。下面总结一些高级技巧:

  1. 变量使用:使用--arg传递外部变量

    jq --arg dept "Engineering" '.users[] | select(.department == $dept)' data.json
  2. 自定义函数:定义可复用的jq函数

    def highlight($msg): ">>> \($msg) <<<"; .[] | highlight(.name)
  3. 错误处理:使用try/catch处理可能缺失的字段

    try .someField catch "default value"
  4. 性能优化:对于大文件,使用--stream模式

    jq --stream 'select(length == 2)' huge.json
  5. 格式化输出:利用@格式转换器

    .[] | [.name, .age] | @tsv

jq的学习曲线可能有些陡峭,但一旦掌握,它将成为你命令行工具箱中最强大的工具之一。建议从简单查询开始,逐步尝试更复杂的转换,最终你将能够轻松处理任何JSON数据挑战。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 11:43:35

SpringBoot+VUE高校固定资产管理系统毕业设计全流程实战指南

&#x1f680; 30款热门AI模型一站整合&#xff0c;DeepSeek/GLM/Qwen 随心用&#xff0c;限时 5 折。 &#x1f449; 点击领海量免费额度 这类毕业设计选题最值得先看的不是功能列表&#xff0c;而是它能不能帮你把选题、开题、任务书、中期检查、程序开发、论文撰写和答辩…

作者头像 李华
网站建设 2026/7/6 11:41:39

解放双手的智能助手:ok-ww鸣潮自动化工具全面解析

解放双手的智能助手&#xff1a;ok-ww鸣潮自动化工具全面解析 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 在快节奏的现代生活中…

作者头像 李华
网站建设 2026/7/6 11:40:55

STM32外部EEPROM存储扩展与I2C通信实践

1. 为什么需要外部EEPROM存储扩展在嵌入式开发中&#xff0c;STM32F446RE这类MCU虽然内置了Flash和SRAM&#xff0c;但实际项目经常会遇到存储空间不足的问题。以我最近参与的工业传感器数据记录项目为例&#xff0c;设备需要持续记录温度、湿度、振动等参数&#xff0c;并保存…

作者头像 李华
网站建设 2026/7/6 11:37:48

Office Online Server 2016 WOPI 集成实战:SpringBoot 服务 5 步对接文档预览

Office Online Server 2016与SpringBoot深度集成&#xff1a;WOPI协议5步实现企业级文档预览 在数字化转型浪潮中&#xff0c;企业文档管理正经历从本地存储到云端协作的革命性转变。想象一下这样的场景&#xff1a;当销售团队需要实时审阅合同条款&#xff0c;当财务部门要协…

作者头像 李华
网站建设 2026/7/6 11:36:47

使用西门子5G无线产品,怎么查看现场的干扰源?

项目背景&#xff1a; 现场使用W788 和W734的配置产品&#xff0c;然后偶尔会出现客户端断网的情况。就想现场分析一下&#xff0c;干扰源在哪里&#xff1f; 需要解决的问题:怎么通过W734的IE浏览器去查看现场的干扰源AP? 解决过程: 登录W734的页面。 然后点击information&…

作者头像 李华