如何从 Zsh 数组中删除所有空字符串?
a=('a' '' 'b' 'c')
# remove empty elements from array
echo ${(j./.)a}
Run Code Online (Sandbox Code Playgroud)
应该输出 a/b/c
gue*_*est 15
有参数扩展${name:#pattern}(模式可以为空),它将对数组的元素起作用:
a=('a' '' 'b' 'c')
echo ${(j./.)a:#}
# If the expansion is in double quotes, add the @ flag:
echo "${(@j./.)a:#}"
Run Code Online (Sandbox Code Playgroud)
man 1 zshexpn:
${name:#pattern}如果模式匹配 name 的值,则替换空字符串;否则,只需替换 name 的值。如果 name 是数组,则删除匹配的数组元素(使用该(M)标志删除不匹配的元素)。
好吧,zsh 有一个:|用于数组减法的参数扩展运算符- 所以一个笨拙的方法是定义一个只包含一个空元素的第二个数组
b=('')
Run Code Online (Sandbox Code Playgroud)
然后做
% echo ${(j./.)a:|b}
a/b/c
Run Code Online (Sandbox Code Playgroud)
但是感觉应该有有一种方法可以在没有额外数组的情况下做到这一点
......确实有。
这就是zsh默认情况下当您不加引号的参数扩展时所做的事情¹。
所以:
a=($a)
Run Code Online (Sandbox Code Playgroud)
将删除$a数组中的空元素。
¹我通常认为这是一个错误的特征。请参阅rc/es或fishshell 以获得更好的数组,但不这样做。这可能是为了提供与ksh/的稀疏数组的某种程度的兼容性bash。ksh/ basharrays 不仅在未加引号的数组扩展时执行空删除(写${a[@]}在那里),而且还拆分 + glob,这意味着你不能真正在那里使用未加引号的数组,除非你禁用 globbing 并设置$IFS为空字符串(IFS=; set -o noglob; a=(${a[@]})然后只在那里执行空删除就像zsh除了使数组非稀疏之外)