我使用以下 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代码中有哪些错误?提前谢谢。
您的解决方案的问题在于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
(又名 readarray
) 将是一个更连贯、更优雅的解决方案,但这仅在 Bash 4 中受支持:
mapfile -t lines <<< "$mytext"
$ printf '[%s]n' "${lines[@]}"
[line one]
[line two]
[line three]
如果没有 -t
标志,mapfile
将保留附加到数组元素的换行符。
这个while循环应该可以工作:
arr=()
while read -r line; do
arr+=("$line")
done <<< "$mytext"
set | grep arr
arr=([0]="line one" [1]="line two" [2]="line three")
不确定您的情况出了什么问题,但这里有一个解决方法:
a=0
while read lines[$a]; do
((a++))
done <<< "${mytext}"
unset lines[$a]; #last iteration has already failed. Unset that index.