我最近意识到readarray
Bash v5. zsh 有等效的吗?
答案1
在 zsh 中没有内置readarray
命令,但它有一个单行表达式,可以实现readarray -t
.
myarray=("${(@f)$(< myfile)}")
要使用stdin
而不是常规文件,我们需要使用cat
:
myarray=("${(@f)$(cat)}")
要捕获命令的输出,您还可以使用:
myarray=("${(@f)$(command)}")
在所有示例中,空行(通过命令替换修剪的尾随行除外)也包含在数组中。如果不想保留空行,请将其更改为:
myarray=(${(f)"$(< myfile)"})
myarray=(${(f)"$(cat)"})
myarray=(${(f)"$(command)"})
f
(对于 line f
eed)实际上是 的缩写 ps[\n]
,s[sep]
在任意分隔符上分割,p
允许转义序列如\n
or\0
和参数扩展sep
。另请参阅0
的快捷方式ps[\0]
。
所以readarray -rd '' array
bash 4.4+的可以这么写array=( "${(@0)$(cat)}" )
。
但有一个重要的区别。对于readarray
,-d
指定一个d
分隔符,而s
参数扩展标志则采用一个s
分隔符。
a<NUL><NUL>b<NUL>c<NUL>
在像,readarray -td '' array
给出array=(a '' b c)
,给出 之类的输入上,array=("${(@0)$(cat)}")
给出array=(a '' b c '')
通常不需要的空尾随元素。可以使用 删除它array[-1]=()
。
NUL 分隔的列表通常用于存储文件路径,因此删除全部空元素array=(${(0)"$(grep -rlZ pattern .)"})
是避免该问题的简单方法。
与 bash 的另一个值得注意的区别readarray
是,在 中array=("${(@f)$(cmd)}")
,保留了 的退出状态cmd
(与 bash 的等效项相反readarray -t array < <(cmd)
)。