You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 07:53:08