Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: this should be easy variable expansion including globs.



On 18/01/17 10:46 AM, Peter Stephenson wrote:
On Wed, 18 Jan 2017 08:13:54 -0800
Ray Andrews <rayandrews@xxxxxxxxxxx> wrote:
$ var1=var1
$ var2=var2
$ var3=var3
$ var99=var99
$ for f ($var*) echo $f
I'm going to regret this, but...
What?  Who me, make a stink about it?  Never.

Seriously, I'd do that Peter if I was creating the variables, and my example makes it look like that, but in fact I'm trying to discover some variables created by a program. It's the 'smartd/smart-notifier' utility which creates a slew of variables all starting with 'SMARTD...' and since it's run via script they all evaporate before I can see what's available to me so I'm wanting to print out 'SMARTD*', that is, all variables starting that way whatever they may be. I had thought of the clumsy:

$ set | grep SMARTD >! somefile
$ cat somefile

... but I expect it can be done elegantly.
===============================

The right way of doing this is to use an array.  It's very similar to
what you've got except you refer to $var[1] rather than $var1.  That
index means the shell knows roughly what you've got on your mind from
the start.

The following syntax may look too good to be true, but does work...

var=(var{1..99})

This is equivalent to

typeset -a var
var[1]=var1
var[2]=var2
...

The first line is there to ensure var is an array.  This is a useful
example as it shows that the array grows as you need it to.

Now the simple "echo" you've got above can be done as

print -lr -- $var

The -l prints one entry per line.  The -r stops any clever expansions so
you get exactly what's in the array.

For most operations, you probably need more control over what you're
doing with entries.  Depending how complicated it gets, your main choices
are the following.

Process every non-empty array entry, regardless of number:

for elt in $var; do
   # $elt in turn refers to elements of the array
   print -r -- $elt
done

Process every entry whether it's empty or not --- there's no distinction
between the two with the values above, it's just a bit of arcanery in
case you need it.

for elt in "${var[@]}"; do
   print -r -- $elt
done

Loop over all 99 elements of... well, anything, but in this case that
array:

integer i
for (( i = 1; i <= 99; i++ )); do
   print -r -- $var[i]
done

If you nonetheless still want to do some completely different, someone
else will no doubt be along in a minute for the usual loooooooong
argument.

pws




Messages sorted by: Reverse Date, Date, Thread, Author