我有一个文件
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
,您可以通过告诉-m3
来grep
停止查看前 3 个匹配项。没有它,grep
将继续,但可能最终被 SIGPIPE 杀死,当它在readln
返回时管道损坏后输出额外的匹配时。
¹只要该选项未启用(交互时即如此),shopt -s lastpipe
就可以避免这种情况bash
monitor
答案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