You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在bash中使用JQ遍历JSON数据并校验各字段取值

实现方案

错误原因

  • 你使用的for循环默认会按任意空白字符(空格、换行、制表符)拆分输入,JSON内容中的空格、字段间隔会导致拆分出的结果不是完整的单个对象
  • 未指定jq提取.data数组的元素,直接输出完整JSON结构,无法按条目拆分

正确实现

方案1:通用场景(无特殊换行字符)

使用-c参数让jq将每个数组成员压缩为单行JSON,配合while read逐行读取,避免拆分混乱

# 假设JSON内容存储在变量$json中
while IFS= read -r item; do
    # 提取各字段存入变量
    seen=$(jq -r '.seen' <<< "$item")
    id=$(jq -r '.id' <<< "$item")
    tinyId=$(jq -r '.tinyId' <<< "$item")
    status=$(jq -r '.status' <<< "$item")
    acknowledged=$(jq -r '.acknowledged' <<< "$item")
    isSeen=$(jq -r '.isSeen' <<< "$item")

    # 此处写入你自己的校验逻辑
    echo "处理条目 $tinyId,状态:$status,是否已读:$isSeen"
done < <(jq -c '.data[]' <<< "$json")

方案2:高性能方案(仅需字段值,不需要操作完整JSON对象)

一次性通过jq把所有字段按制表符拼接输出,单次读取所有变量,避免循环内反复调用jq

while IFS=$'\t' read -r seen id tinyId status acknowledged isSeen; do
    # 直接使用提取后的变量即可
    echo "处理条目 $tinyId,状态:$status,是否已读:$isSeen"
done < <(jq -r '.data[] | [.seen, .id, .tinyId, .status, .acknowledged, .isSeen] | join("\t")' <<< "$json")

方案3:极端兼容场景(字段包含换行、特殊字符)

通过base64编码转义特殊字符,完全避免拆分异常

while IFS= read -r item_b64; do
    item=$(base64 -d <<< "$item_b64")
    seen=$(jq -r '.seen' <<< "$item")
    id=$(jq -r '.id' <<< "$item")
    tinyId=$(jq -r '.tinyId' <<< "$item")
    status=$(jq -r '.status' <<< "$item")
    acknowledged=$(jq -r '.acknowledged' <<< "$item")
    isSeen=$(jq -r '.isSeen' <<< "$item")

    # 校验逻辑
done < <(jq -r '.data[] | @base64' <<< "$json")

注意事项

  • 优先使用进程替换< <(命令)的方式将jq输出传入while循环,避免管道写法jq ... | while ...触发子shell,导致循环内定义的变量外部无法访问
  • jq的-r参数会输出原始字符串,自动去掉JSON值的双引号,适合直接存入bash变量使用

内容的提问来源于stack exchange,提问作者Dave Shaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:36:02