Slicing an array that contains empty strings

arrayzsh

Consider the array foo, initialized like this:

$ foo=( a b '' d e f g )

foo contains 7 elements, one of which is an empty string.

Below are a few ways to print out the contents of foo, using the print built-in:

$ print -rl -- $foo
a
b
d
e
f
g
$ print -rl -- "$foo"
a b  d e f g
$ print -rl -- $foo[@]
a
b
d
e
f
g
$ print -rl -- "$foo[@]"
a
b

d
e
f
g

Note that only the form whose last token is "$foo[@]" interprets it as 7 separate arguments.

Now, suppose that I wanted to use print -rl -- ... to display only the first 5 elements of foo, one element per line?

This won't work:

$ print -rl -- "$foo[1,5]"
a b  d e

Nor this:

$ print -rl -- $foo[1,5]
a
b
d
e

I've tried other variants, but they all fail to produce the desired output, namely

a
b

d
e

What's the slice-equivalent of the full "$foo[@]"?

If no such equivalent exists, how do I create an array bar consisting of the first 5 elements of foo?

Best Answer

Though zsh doesn't do split+glob upon parameter expansion, it still does empty removal, so that's still one reason you want to quote variables there, so:

print -rl -- "$var[@]"

Or

print -rl -- "${(@)var}"

Those @ are to get Bourne "$@"-like behaviour.

For elements 1 to 5:

print -rl -- "${(@)var[1,5]}"

The ksh-like variant will also work:

print -rl -- "${(@)var:0:5}"
Related Question