Shell脚本:如何将含空格的文本行完整存入数组
解决Shell脚本按行读取文本到数组的问题
问题根源
你当前用myArray=(cat "$filename")的写法会触发Shell的单词拆分:默认情况下,Shell以空格、制表符、换行符作为分隔符(由IFS环境变量控制),所以带空格的行被拆分成了多个数组元素。此外,你生成title.txt的过程也存在问题:echo $cmd和echo $(jq ...)未加引号,会丢失换行符,导致title.txt里的标题挤在一起,进一步影响数组读取结果。
完整修复方案
1. 修正title.txt的生成逻辑
原来的写法会破坏JSON和标题的换行结构,改成以下方式:
#!/bin/bash # 建议改用bash,sh对数组特性的支持有限 # 直接将curl结果传给jq,无需临时文件Data.json(可选优化) jq '.[] | .title' < <(curl https://jsonplaceholder.typicode.com/todos) > title.txt echo "text file creation done!"
如果需要保留Data.json文件:
curl https://jsonplaceholder.typicode.com/todos > Data.json jq '.[] | .title' Data.json > title.txt
2. 按行读取文本到数组的正确写法
方法一:使用mapfile(bash 4.0及以上推荐)
mapfile是bash内置命令,专门用于按行读取文件到数组,不会拆分带空格的行:
filename=title.txt declare -a myArray mapfile -t myArray < "$filename"
-t参数会自动去掉每行末尾的换行符,符合你的需求。
方法二:循环读取(兼容旧版bash)
如果你的bash版本低于4.0,用while循环逐行读取:
filename=title.txt declare -a myArray while IFS= read -r line; do myArray+=("$line") done < "$filename"
IFS=:避免读取时自动忽略行首或行尾的空格-r:禁止反斜杠转义,保留行内的原始字符
3. 修复后的完整脚本
#!/bin/bash # 生成title.txt curl https://jsonplaceholder.typicode.com/todos > Data.json jq '.[] | .title' Data.json > title.txt echo "text file creation done!" filename=title.txt declare -a myArray # 使用mapfile读取每行到数组 mapfile -t myArray < "$filename" # 打印所有数组元素 printf '%s\n' "${myArray[@]}" # 遍历数组(改用数组实际长度,更灵活) for (( i = 0 ; i < ${#myArray[@]} ; i++)) do echo "Element [$i]: ${myArray[$i]}" done
关键知识点
- 单词拆分:Shell执行命令替换或变量展开时,会根据
IFS拆分内容,直接用$(cat file)赋值数组会拆分带空格的行。 - 引号的作用:变量或命令替换时加双引号
"$var"、"$(cmd)",能避免不必要的单词拆分和换行丢失。 - 按行读取的正确方式:
mapfile或while read循环能完整保留每行内容,不会触发单词拆分。
内容的提问来源于stack exchange,提问作者Ram Kashyap
相关产品推荐
相关产品推荐

