How do I remove all empty strings from a Zsh array?
a=('a' '' 'b' 'c')
# remove empty elements from array
echo ${(j./.)a}
Should output a/b/c
There is the parameter expansion ${name:#pattern} (pattern can be empty), which will work on elements of an array:
a=('a' '' 'b' 'c')
echo ${(j./.)a:#}
# If the expansion is in double quotes, add the @ flag:
echo "${(@j./.)a:#}"
man 1 zshexpn:
${name:#pattern}If the pattern matches the value of name, then substitute the empty string; otherwise, just substitute the value of name. If name is an array the matching array elements are removed (use the(M)flag to remove the non-matched elements).
That's what zsh does by default when you leave a parameter expansion unquoted¹.
So:
a=($a)
Will remove the empty elements in the $a array.
¹ I generally consider that a misfeature. See the rc/es or fish shells for better arrays that don't do that. That's probably there so as to provide some level of compatibility with the sparse arrays of ksh/bash. ksh/bash arrays not only do empty removal upon unquoted array expansion (written ${a[@]} there), but also split+glob, which means you can't really use arrays unquoted there unless you disable globbing and set $IFS to the empty string (IFS=; set -o noglob; a=(${a[@]}) then does empty removal only there like in zsh in addition to making the array non-sparse)
"$array[@]" or "${(@)array}", to expand to all the elements including empty ones. "$array" is like "$array[*]" which is the elements joined with the first character of $IFS.
"$@".
Well, zsh has a :| parameter expansion operator for array subtraction - so a klunky way to do it would be to define a second array consisting of only an empty element
b=('')
and then do
% echo ${(j./.)a:|b}
a/b/c
However it feels like there ought to be a way to do it without the additional array
... and indeed there is.