zsh 是否有相当于 bash 内置 readarray 的功能?

oco*_*odo 12 bash zsh

我最近意识到readarrayBash v5. zsh 有等效的吗?

oco*_*odo 14

在 zsh 中没有内置readarray命令,但它有一个单行表达式,可以实现readarray -t.

myarray=("${(@f)$(< myfile)}")
Run Code Online (Sandbox Code Playgroud)

要使用stdin而不是常规文件,我们需要使用cat

myarray=("${(@f)$(cat)}")
Run Code Online (Sandbox Code Playgroud)

要捕获命令的输出,您还可以使用:

myarray=("${(@f)$(command)}")
Run Code Online (Sandbox Code Playgroud)

在所有示例中,空行(通过命令替换修剪的尾随行除外)也包含在数组中。如果不想保留空行,请将其更改为:

myarray=(${(f)"$(< myfile)"})
myarray=(${(f)"$(cat)"})
myarray=(${(f)"$(command)"})
Run Code Online (Sandbox Code Playgroud)

f(对于 line feed)实际上是 的缩写 ps[\n]s[sep]在任意分隔符上分割,p允许转义序列如\nor\0和参数扩展sep。另请参阅0的快捷方式ps[\0]

所以readarray -rd '' arraybash 4.4+的可以这么写array=( "${(@0)$(cat)}" )

但有一个重要的区别。对于readarray,-d指定一个d分隔符,而s参数扩展标志则采用一个s分隔符。

On an input like a<NUL><NUL>b<NUL>c<NUL>, readarray -td '' array gives array=(a '' b c), while array=("${(@0)$(cat)}") gives array=(a '' b c '') with a generally unwanted empty trailing element. It can be removed with array[-1]=().

NUL-delimited lists are often used to store file paths though, so removing all empty elements as array=(${(0)"$(grep -rlZ pattern .)"}) does is an easy way to avoid the problem.

Another noteworthy difference with bash's readarray is that in array=("${(@f)$(cmd)}"), the exit status of cmd is preserved (contrary to with bash's readarray -t array < <(cmd) equivalent).