Bash遍历jq输出时出现额外字符及JSON数组解析问题
问题分析与解决方法
核心问题
你的脚本存在两个关键问题:
- DATA并非bash数组:
DATA=$(...)赋值的是完整的JSON数组字符串,不是bash的数组结构。"${DATA[@]}"只会把整个字符串当作数组的唯一元素,循环仅执行一次。 - jq提取逻辑错误:循环里用
.[] | .project会遍历整个JSON数组的所有元素,把所有project值一次性输出,导致多个值拼接在一起(比如你看到的some_proj_namepy其实是两个项目名的叠加)。
正确解决方法
方法一:直接逐行处理单个JSON对象(推荐)
修改jq命令,去掉外层数组包装,让每个对象单独输出一行,再用while read循环逐行读取处理:
#!/bin/bash curl -X GET https://$BASEURL/rest/api/latest/repos \ -H "accept: application/json" \ -H "authorization: Bearer $APIKEY" \ | jq -c '.values[] | {project: .slug, repo: .project.key}' \ | while read -r repo_obj do PROJ=$(jq -r '.project' <<< "$repo_obj") REPO=$(jq -r '.repo' <<< "$repo_obj") echo "$PROJ" echo "$REPO" done
jq -c '.values[] | ...'会遍历API返回的values数组,把每个处理后的对象以紧凑格式输出为单独一行。while read -r repo_obj逐行读取每个JSON对象,此时repo_obj是单个对象,直接用.project和.repo就能提取对应值。
方法二:将JSON对象存入bash数组后遍历
如果需要先把所有对象存入bash数组再处理,可以用readarray加载jq输出的每行内容:
#!/bin/bash # 把每个JSON对象作为数组元素存入DATA readarray -t DATA < <(curl -X GET https://$BASEURL/rest/api/latest/repos \ -H "accept: application/json" \ -H "authorization: Bearer $APIKEY" \ | jq -c '.values[] | {project: .slug, repo: .project.key}') # 遍历数组处理每个对象 for repo_obj in "${DATA[@]}" do PROJ=$(jq -r '.project' <<< "$repo_obj") REPO=$(jq -r '.repo' <<< "$repo_obj") echo "$PROJ" echo "$REPO" done
readarray -t DATA会把jq输出的每一行(单个JSON对象)作为数组的一个元素。- 遍历数组时,每个
repo_obj都是独立的JSON对象,直接提取属性即可。
内容的提问来源于stack exchange,提问作者Jeremy Fiel
相关产品推荐
相关产品推荐

