将多行字符串读入数组时出错?

时间:2014-02-27 13:24:15

标签: arrays bash

我使用以下bash代码想要将多行字符串读入数组。我希望每个数组元素对应一个字符串行。

mytext="line one
line two
line three"
IFS=$'\n' read -a lines <<<"${mytext}"
echo "len=${#lines[@]}"
for line in "${lines[@]}"
do
   echo "[$line]"
done

我希望“len”应该等于3,并且“lines”数组应该正确初始化。但是,我得到了以下结果:

len=1
[line one]

我使用了错误的“IFS”吗? bash代码中有哪些错误? 提前谢谢。

3 个答案:

答案 0 :(得分:6)

你的解决方案出了什么问题,read总是一次读取一行,所以告诉它IFS是换行符会让它读取整行到数组的第一个元素。每次read,您仍会覆盖整个阵列。您可以迭代地构建数组:

lines=()
while read; do
  lines+=("$REPLY")
done <<< "$mytext"

或通过换换其他内容的换行符:

IFS='+' read -a lines <<< "${mytext//$'\n'/+}"
$ IFS=@
$ echo "${lines[*]}"
line one@line two@line three

使用mapfile(a.k.a。readarray)将是一个更加连贯,优雅的解决方案,但这仅在Bash 4中得到支持:

mapfile -t lines <<< "$mytext"

$ printf '[%s]\n' "${lines[@]}"
[line one]
[line two]
[line three]

如果没有-t标记,mapfile将保持新行附加到数组元素。

答案 1 :(得分:1)

这个while循环应该有效:

arr=()
while read -r line; do
   arr+=("$line")
done <<< "$mytext"

set | grep arr
arr=([0]="line one" [1]="line two" [2]="line three")

答案 2 :(得分:1)

不确定您的情况有什么问题,但这是一种解决方法:

a=0
while read lines[$a]; do
    ((a++))
done <<< "${mytext}"
unset lines[$a]; #last iteration has already failed. Unset that index.