我使用以下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代码中有哪些错误? 提前谢谢。
答案 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.