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

Re: this should be easy variable expansion including globs.




18.01.2017, 22:53, "Ray Andrews" <rayandrews@xxxxxxxxxxx>:
> 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.

Why are you trying this? `set | grep …` is only bad if you need to use the results in a script, but now it looks like you are reading `somefile` manually.

Alternative solutions are using `typeset -m 'SMARTD*'` (you did know about `which -m`, did not you? This is similar.) And using zsh/parameter module, there will be $parameters associative array which may be searched by indexing (find `Subscript Flags` section in man pages, though I failed to construct a useful subscript) and definitely can be processed in a cycle.

> ===============================
>>  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