如何打破 grep -E 结果

如何打破 grep -E 结果

我有一个文件

gretting: hello the world
gretting: good morning
gretting: good evening
Gbye: goodbye
Gbye: see you

我分配一个变量

var = grep -E -i "greeting"

那么 var 等于 3 行问候语

var = "gretting: hello the world
gretting: good morning
gretting: good evening"

我如何将 var 分解到每一行并将其分配给其他变量,例如temp1,,temp2..

temp1 = "gretting: hello the world
temp2 = "gretting: good morning
temp3 = "gretting: good evening"

谢谢

答案1

请注意,这是在模式中-E从基本正则表达式切换到扩展正则表达式语法的选项。E

在 中gretting,没有基本或扩展的正则表达式运算符,因此-E没有什么区别,您也可以使用-F固定F字符串。

要将前 3 行分配给 3 个不同的 shell 变量,在类似 POSIX 的 shell 中,您可以执行以下操作:

readln() for _var; do IFS= read -r "$_var"; done

grep -Fi gretting file | readln temp1 temp2 temp3

但请注意,在包括(默认情况下)在内的多个 shell 中bash,管道的最右侧部分在子 shell 中运行,因此一旦管道重新调整,这些变量就会丢失,因此您需要在同一管道组件中使用它们:

grep -Fi gretting file | {
  readln temp1 temp2 temp3
  do-something-with "$temp1" "$temp2" "$temp3"
}

或者使用 ksh 风格:

readln temp1 temp2 temp3 < <(grep -Fi gretting file)

或者在 yash 中:

readln temp1 temp2 temp3 <(grep -Fi gretting file)

其中grep在后台运行,其输出是从当前 shell 中的管道读取的。

通过 GNU 实现grep,您可以通过告诉-m3grep停止查看前 3 个匹配项。没有它,grep将继续,但可能最终被 SIGPIPE 杀死,当它在readln返回时管道损坏后输出额外的匹配时。


¹只要该选项未启用(交互时即如此),shopt -s lastpipe就可以避免这种情况bashmonitor

答案2

$ grep -i gretting file
gretting: hello the world
gretting: good morning
gretting: good evening

$ readarray -d $'\n' -t temp < <(grep -i gretting file)

$ echo "${temp[0]}"
gretting: hello the world
$ echo "${temp[1]}"
gretting: good morning
$ echo "${temp[2]}"
gretting: good evening

或者如果您出于某种原因想使用中间标量变量:

$ var=$(grep -i gretting file)

$ readarray -d $'\n' -t temp <<<"$var"

$ echo "${temp[0]}"
gretting: hello the world
$ echo "${temp[1]}"
gretting: good morning
$ echo "${temp[2]}"
gretting: good evening

相关内容