我需要验证一些程序输出。我知道输出正好包含三行,我想将它们存储在不同的变量中以便于访问。我尝试了以下几种变体,但均未成功。
IFS=$'\n' read line1 line2 line3 <<< $(grep pattern file.log)
IFS='' read line1 line2 line3 <<< $(grep pattern file.log)
是否可以结合read
并<<<
做我想做的事?如何?
如果不可能,有什么解释?你建议什么替代方案?
谢谢你。
我需要验证一些程序输出。我知道输出正好包含三行,我想将它们存储在不同的变量中以便于访问。我尝试了以下几种变体,但均未成功。
IFS=$'\n' read line1 line2 line3 <<< $(grep pattern file.log)
IFS='' read line1 line2 line3 <<< $(grep pattern file.log)
是否可以结合read
并<<<
做我想做的事?如何?
如果不可能,有什么解释?你建议什么替代方案?
谢谢你。
{
read line1
read line2
read line3
} < <(grep pattern file.log)
我觉得$()
在字符串 ( ) 之后放置命令替换 ( <<<
) 是一种不必要的扭曲,就像试图read
一次读取多行一样。这是复合命令中的多个read
s 是自然解决方案的情况。
好吧,我已经找到了如何让它发挥作用。它取决于双引号的使用。
首先我尝试了这个:
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
and<<<
有一个微妙但重要的缺点:空白行将完全消失。
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"
内部双引号括起来以扩展换行符。
设置IFS
为\n
并传递-d ''
给read
。您也可以使用进程替换而不是此处的字符串
while IFS=$'\n' read -d'' -r line1 line2 line3; do :; done < <(grep pattern file.log)
使用数组
read -a array < <(grep pattern file.log)
# Optional
line1=${array[0]}
line2=${array[1]}
line3=${array[2]}
但是,我会推荐小次郎的回答。
while read -r arry[x]; do
((x++));
done < <(grep pattern file.log)
这将创建一个名为的数组arry
,3 行将属于从 0 开始的每个索引。