Is there a way to find the length of the array *(files names) in zsh without using a for loop to increment some variable?
I naively tried echo ${#*[@]} but it didn't work. (bash syntax are welcome as well)
Is there a way to find the length of the array *(files names) in zsh without using a for loop to increment some variable?
I naively tried echo ${#*[@]} but it didn't work. (bash syntax are welcome as well)
${#*[@]} would be the length of the $* array also known as $@ or $argv, which is the array of positional parameters (in the case of a script or function, that's the arguments the script or function received). Though you'd rather use $# for that.
* alone is just a glob pattern. In list context, that's expanded to the list of files in the current directory that match that pattern. As * is a pattern that matches any string, it would expand to all file names in the current directory (except for the hidden ones).
Now you need to find a list context for that * to be expanded, and then somehow count the number of resulting arguments. One way could be to use an anonymous function:
() {echo There are $# non hidden files in the current directory} *(N)
Instead of *, I used *(N) which is * but with the N (for nullglob) globbing qualifier which makes it so that if the * pattern doesn't match any file, instead of reporting an error, it expands to nothing at all.
The expansion of *(N) is then passed to that anonymous function. Within that anonymous function, that list of file is available in the $@/$argv array, and we get the length of that array with $# (same as $#argv, $#@, $#* or even the awkward ksh syntax like ${#argv[@]}).
files=(*)
printf 'There are %d files\n' "${#files[@]}"
or
set -- *
printf 'There are %d files\n' "$#"
You have to name the array first (as I did above with files) or use the built-in array $@ by populating it with the wildcard, as I did in the second example. In the former, the "length" (number of files) of the array is done with the ${#arrayname[@]} syntax. The number of elements in the built-in array is in $#.