Bash遍历含多行的字符串时遇到的拆分异常问题
解决Bash中遍历多行JSON字符串的异常问题
问题根源
- 第一种
for循环:Shell默认以空格、制表符、换行符作为分词分隔符,带空格的{"name":"a b"}会被拆分成两个独立条目。 - 第二种
while read:未给变量$lines添加双引号,导致Shell将变量内的换行符替换为空格,所有内容合并成一行处理。
解决方案
方案1:修复while read的变量引用
给变量加上双引号,保留原始换行格式:
file='[ {"name" : "a b"}, { "name" : "c" }, { "name" : "d" } ]' lines=$(jq -c '.[]' <<< "$file") echo "\niterating fixed #2:" while read -r line; do echo "item: $line" done <<< "$lines"
执行结果:
item: {"name":"a b"} item: {"name":"c"} item: {"name":"d"}
方案2:直接通过管道处理jq输出(推荐)
跳过变量存储环节,直接将jq的输出通过管道传给while read,避免变量处理时的格式丢失:
file='[ {"name" : "a b"}, { "name" : "c" }, { "name" : "d" } ]' echo "\niterating via pipe:" jq -c '.[]' <<< "$file" | while read -r line; do echo "item: $line" done
这种方式更可靠,能保证每一行JSON条目的独立性,尤其适合处理复杂内容。
方案3:处理含特殊字符的JSON条目(进阶)
如果JSON条目内部包含换行符等特殊字符,可使用jq的--null-input参数输出以null分隔的结果,再用read -d ''读取:
echo "\niterating with null separator:" jq -c --null-input '.[]' <<< "$file" | while IFS= read -r -d '' item; do echo "item: $item" done
该方法能确保即使条目内部存在换行,也不会被错误拆分。
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

