在Bash脚本中使用jq解析JSON并提取字段至变量的问题
在Bash中用jq解析JSON数组并提取值到变量和数组
我完全懂你的困扰——直接用jq -r '.[] | .annonce_id, .titre_slug, .photos'输出的内容是零散的行,根本没法对应到每个对象的三个字段,更别说把photos转成Bash数组了。下面给你一个安全且可靠的解决方案,能完美处理每个对象的字段,包括多元素的photos数组:
完整脚本示例
首先,我们先把你的JSON数据处理成每个对象一行、字段用制表符分隔的格式(避免特殊字符干扰),再用Bash循环逐个读取并转换:
# 定义你的JSON数据(也可以从文件读取,比如< data.json) json_data='[ {"annonce_id":"123","photos":["url_01"],"titre_slug":"slug1"}, {"annonce_id":"456","photos":["url_11","url_12"],"titre_slug":"slug2"}, {"annonce_id":"7890","photos":["url_31"],"titre_slug":"slug3"}, {"annonce_id":"1234","photos":["url_41"],"titre_slug":"slug4"}, {"annonce_id":"5678","photos":["url_51"],"titre_slug":"slug5"}, {"annonce_id":"90123","photos":["url_61"],"titre_slug":"slug6"} ]' # 遍历每个JSON对象,提取字段到变量和数组 while IFS=$'\t' read -r annonce_id titre_slug photos_json; do # 将photos的JSON数组转换成Bash数组 readarray -t photos < <(jq -r '.[]' <<< "$photos_json") # 这里可以添加你的业务逻辑,比如使用这些变量 echo "=== 处理广告ID: $annonce_id ===" echo "Slug标题: $titre_slug" echo "图片列表:" for photo_url in "${photos[@]}"; do echo " - $photo_url" done done < <(jq -r '.[] | [.annonce_id, .titre_slug, .photos] | @tsv' <<< "$json_data")
关键步骤解释
- jq格式化输出:
用jq -r '.[] | [.annonce_id, .titre_slug, .photos] | @tsv'把每个JSON对象的三个字段打包成一行,用制表符分隔(@tsv会自动处理字段里的特殊字符,避免分割出错)。 - Bash循环读取:
while IFS=$'\t' read -r annonce_id titre_slug photos_json会把每行的三个制表符分隔字段分别存入annonce_id、titre_slug变量,以及photos_json(这是photos数组的JSON字符串)。 - 转换photos为Bash数组:
readarray -t photos < <(jq -r '.[]' <<< "$photos_json")用jq把photos的JSON数组拆成单个元素,再用readarray存入Bash数组photos,这样就能直接遍历数组元素了。
扩展:从文件读取JSON
如果你的JSON数据保存在文件(比如data.json)里,只需要把脚本里的<<< "$json_data"换成< data.json即可:
while IFS=$'\t' read -r annonce_id titre_slug photos_json; do # 同上的处理逻辑 done < <(jq -r '.[] | [.annonce_id, .titre_slug, .photos] | @tsv' < data.json)
这个方法完全避免了不安全的eval操作,同时能处理包含空格、特殊字符的字段,稳定性拉满~
内容的提问来源于stack exchange,提问作者MarvinLeRouge
相关产品推荐
相关产品推荐

