我发现如何让它运作了。关键在于使用双引号。
首先,我尝试了这个:
data=$(grep pattern file.log)
IFS=$'\n' read -d '' -r line1 line2 line3 <<< "$data"
后来发现如果我保留双引号,这个变量其实并不是必须的:
IFS=$'\n' read -d '' -r line1 line2 line3 <<< "$(grep pattern file.log)"
默认情况下,换行符表示数据结束。为了避免read
在第一行后停止工作,我使用-d ''
覆盖了默认设置。
默认情况下,字段分隔符是<space><tab><newline>
。由于我想读取整行,所以将IFS设置为$'\n'
。
请注意,-r
并不是解决方案的核心。我添加它是为了避免输入中的反斜杠引起问题。
编辑
使用read
和<<<
有一个微妙但重要的缺点:空行将完全消失。
data="1
3"
IFS=$'\n' read -d '' -r line1 line2 line3 <<< "$data"
echo ${line1:-blank}
echo ${line2:-blank}
echo ${line3:-blank}
output:
1
3
blank
如果您尝试使用-a
将行存储到数组中,情况也是一样的:
IFS=$'\n' read -d '' -r -a line_ar <<< "$data"
echo ${line_ar[0]:-blank}
echo ${line_ar[1]:-blank}
echo ${line_ar[2]:-blank}
output:
1
3
blank
然而,您仍将使用以下结构获取所有行:
while read -r line ; do
echo ${line:-blank}
done <<< "$data"
output:
1
blank
3
如果行数非常有限,则最好像kojiro建议的那样使用多个读取。然而,使用<<<
是完全合法的:
{
read -r line1
read -r line2
read -r line3
} <<< "$data"
echo ${line1:-blank}
echo ${line2:-blank}
echo ${line3:-blank}
记得将"$var"
用双引号括起来,以展开换行符。