Bash使用jq解析JSON生成数组时值含空格输出错乱问题
问题根因
- 核心触发点是Bash默认的单词拆分规则:你使用
array=($(命令输出))的方式给数组赋值时,Bash会按照默认的内部字段分隔符(IFS,包含空格、制表符、换行符)将命令输出的所有内容切割为独立的数组元素,不会区分空格是字段分隔符还是value值本身的内容。
你的代码中先把jq输出的多行结果用tr '\n' ' '转成了空格分隔的单行长文本,带空格的value会被拆成多个数组元素:比如2. this is string value of record 2 with spaces会被拆成"2.、this、is等十几个独立元素,导致record2数组长度远大于record数组的3个元素,按索引对应取值时自然错位。 - 另外你JSON中的value字段额外嵌套了一层双引号,直接输出会携带多余的引号,和期望输出不符。
修复方案
直接用readarray(Bash 4.0及以上版本支持)按行读取jq的输出存为数组,每行作为一个独立的数组元素,不会被内部空格拆分,同时调整jq规则去掉多余的外层引号:
#!/bin/bash json_data=$(cat <<EOF { "records":[ { "name":"record1", "value":"\"1.this-is-string-value-of-record-1-with-no-spaces\"" }, { "name":"record2", "value":"\"2. this is string value of record 2 with spaces\"" }, { "name":"record3", "value":"\"3. this is string value of record 3 with spaces\"" } ] } EOF ) # 按行读取name存为数组,避免空格拆分 readarray -t record < <(echo "${json_data}" | jq -r ".records[].name") # 按行读取value存为数组,同时用jq去掉多余的外层双引号 readarray -t record2 < <(echo "${json_data}" | jq -r ".records[].value | fromjson") # 遍历输出 for i in "${!record[@]}"; do echo "The record [ ${record[i]} ] belongs to [ ${record2[i]} ]" done
运行后即可完全匹配你期望的输出。
内容的提问来源于stack exchange,提问作者Kalib Zen
相关产品推荐
相关产品推荐

