如何用<<<<<<<<<运营商?

时间:2013-07-10 18:06:17

标签: bash

我需要验证一些程序输出。我知道输出包含三行,我想存储在不同的变量中以便于访问。我尝试了以下几种变体而没有成功。

IFS=$'\n' read line1 line2 line3 <<< $(grep pattern file.log)
IFS='' read line1 line2 line3 <<< $(grep pattern file.log)

是否可以将read<<<结合起来做我想要的事情?怎么样?

如果不可能,解释是什么?你有什么选择吗?

谢谢。

5 个答案:

答案 0 :(得分:5)

{
    read line1
    read line2
    read line3
} < <(grep pattern file.log) 

我觉得在一个herestring($())之后放置一个命令替换(<<<)  是一种不必要的扭曲,就像试图让read一次读取多行一样。这种情况是复合命令中的多个read是自然解决方案。

答案 1 :(得分:1)

IFS设为\n并将-d ''传递给read。您也可以使用进程替换而不是here string

while IFS=$'\n' read -d'' -r line1 line2 line3; do :; done < <(grep pattern file.log)

答案 2 :(得分:1)

好吧,我已经找到了如何让它发挥作用。它取决于双引号的使用。

首先我尝试了这个:

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"括在双引号内以扩展换行符。

答案 3 :(得分:0)

使用数组

read -a array < <(grep pattern file.log)
# Optional
line1=${array[0]}
line2=${array[1]}
line3=${array[2]}

但是,我建议kojiro's answer

答案 4 :(得分:0)

while read -r arry[x]; do 
    ((x++)); 
done < <(grep pattern file.log)

这将创建一个名为arry的数组,3行将属于从0开始的每个索引。