我想从子 shell 实例化一个 zsh 数组
myarray=($(somecommand)
我检查是否收到了我想要的东西
for element in $myarray ; do echo "===" ; echo $element ; echo "---" ; done
默认情况下,我看到空格(空格和换行符)用于分隔元素。
我还发现可以使用${(s:-:)"$(somecommand)"}
by 分隔-
,在这种情况下,空格和换行符不会破坏元素(即数组元素可以包含换行符)。
到目前为止,我无法仅在换行符处进行分割。即如果somecommand
返回
Alice
Bob
Arthur C Clarke
Neo
Thomas Anderson
我希望for
打印上面的循环:
===
Alice
---
===
Bob
---
===
Arthur C Clarke
---
===
Neo
---
===
Thomas Anderson
---
我该如何实现这一目标? (可能还指出在手册中查找该内容的位置。)
答案1
本机拆分运算符(除了$IFS
在不带引号的命令替换上完成的类似 Bourne 的单词拆分之外)带有s
参数扩展标志:
array=(${(ps:\n:)"$(cmd)"})
cmd
将拆分换行符的输出,丢弃空元素(空行)。
p
是为了启用这些\x
扩展。与ps:\n:
常见的一样,它有一个更短的别名:(f
在线拆分F种子):
array=(${(f)"$(cmd)"})
要保留空行,您可以这样做:
array=("${(f@)$(cmd)"})
现在,请注意,像在大多数其他 shell 中一样,命令替换条全部尾随换行符,因此所有尾随空行。要保留这些,您可以执行以下操作:
array=("${(f@)$(cmd; echo .)}")
array[-1]=() # remove that last line added by echo .
通过$IFS
分词:
IFS=$'\n'
array=($(cmd)) # removes empty lines. Note that contrary to other
# Bourne-like shells, zsh doesn't do globbing there
# so you don't need the "set -o noglob"
IFS=$'\n\n' # like in ksh93, doubling an IFS-whitespace character
# removes its special treatment as a whitespace character
array=($(cmd)) # preserves empty lines except the trailing ones
IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=() # preserves all empty lines.
为了避免$IFS
全局修改,您可以在匿名函数中执行上述操作:
(){
local IFS=$'\n\n'
array=($(cmd; echo .)); array[-1]=()
}
另请注意,$array
扩展会跳过空元素。所以如果你想循环全部包括空元素在内的元素,您需要:
for i ("$array[@]") ...
或者
for i ("${(@)array}") ...
不是
for i ($array) ...
for i in $array