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

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

我最近意识到readarrayBash 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 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分隔符。

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))。

答案2

zsh 有一个叫做mapfile,但它是一个模块并且必须加载才能使用,并且它不是与readarray.

zmodload zsh/mapfile
filename='...'
filelines=("${(@f)mapfile[$filename]}")

其目的(@f)与此处的其他答案相同,即在换行符上拆分文件的内容。

相关内容