zsh-users
 help / color / mirror / code / Atom feed
* this should be easy variable expansion including globs.
@ 2017-01-18 16:13 Ray Andrews
  2017-01-18 18:46 ` Peter Stephenson
  0 siblings, 1 reply; 6+ messages in thread
From: Ray Andrews @ 2017-01-18 16:13 UTC (permalink / raw)
  To: Zsh Users

$ var1=var1

$ var2=var2

$ var3=var3

$ var99=var99

$ for f ($var*) echo $f


var1

var2

var3

var99


... How do I do what I'm trying to do there?  This reminds me a bit of 
my previous issue with 'whence -m' where the glob refers to a pattern, 
not a list of files but I can't get the syntax right. Everything I 
google presumes the latter (file globbing).




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: this should be easy variable expansion including globs.
  2017-01-18 16:13 this should be easy variable expansion including globs Ray Andrews
@ 2017-01-18 18:46 ` Peter Stephenson
  2017-01-18 19:51   ` Ray Andrews
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 2017-01-18 18:46 UTC (permalink / raw)
  To: Zsh Users

On Wed, 18 Jan 2017 08:13:54 -0800
Ray Andrews <rayandrews@eastlink.ca> wrote:
> $ var1=var1
> $ var2=var2
> $ var3=var3
> $ var99=var99
> $ for f ($var*) echo $f

I'm going to regret this, but...

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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: this should be easy variable expansion including globs.
  2017-01-18 18:46 ` Peter Stephenson
@ 2017-01-18 19:51   ` Ray Andrews
  2017-01-18 20:12     ` Nikolay Aleksandrovich Pavlov (ZyX)
       [not found]     ` <484161484770354__27207.6165573255$1484770824$gmane$org@web26m.yandex.ru>
  0 siblings, 2 replies; 6+ messages in thread
From: Ray Andrews @ 2017-01-18 19:51 UTC (permalink / raw)
  To: zsh-users

On 18/01/17 10:46 AM, Peter Stephenson wrote:
> On Wed, 18 Jan 2017 08:13:54 -0800
> Ray Andrews <rayandrews@eastlink.ca> 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
>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: this should be easy variable expansion including globs.
  2017-01-18 19:51   ` Ray Andrews
@ 2017-01-18 20:12     ` Nikolay Aleksandrovich Pavlov (ZyX)
  2017-01-18 20:30       ` Ray Andrews
       [not found]     ` <484161484770354__27207.6165573255$1484770824$gmane$org@web26m.yandex.ru>
  1 sibling, 1 reply; 6+ messages in thread
From: Nikolay Aleksandrovich Pavlov (ZyX) @ 2017-01-18 20:12 UTC (permalink / raw)
  To: Ray Andrews, zsh-users



18.01.2017, 22:53, "Ray Andrews" <rayandrews@eastlink.ca>:
> On 18/01/17 10:46 AM, Peter Stephenson wrote:
>>  On Wed, 18 Jan 2017 08:13:54 -0800
>>  Ray Andrews <rayandrews@eastlink.ca> 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


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: this should be easy variable expansion including globs.
       [not found]     ` <484161484770354__27207.6165573255$1484770824$gmane$org@web26m.yandex.ru>
@ 2017-01-18 20:20       ` Daniel Shahaf
  0 siblings, 0 replies; 6+ messages in thread
From: Daniel Shahaf @ 2017-01-18 20:20 UTC (permalink / raw)
  To: Nikolay Aleksandrovich Pavlov (ZyX); +Cc: Ray Andrews, zsh-users

Nikolay Aleksandrovich Pavlov (ZyX) wrote on Wed, Jan 18, 2017 at 23:12:34 +0300:
> Alternative solutions are […] 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.

% typeset -p ${(k)parameters[(I)SMART*]} >! somefile

1. $parameters is an associative array mapping parameter names to
I don't know what.

2. (I)SMART* causes the parameter expansion to match all key-value pairs
where the key matches "SMART*".

3. (k) means: for each matched pair, the expansion shall contain the
key.

Bug: when there are no variables named SMART*, this will run «typeset
-p» which will output all variables.  You could guard against that with
.
    local -a names=( ${(k)…} )
    (( $#names )) || return 1

-------

Now, having said all that: the Internet says that the smartd(8) man page
documents the available parameters.  That isn't the case on my box, but
my smartd(8) might be out of date.

Cheers,

Daniel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: this should be easy variable expansion including globs.
  2017-01-18 20:12     ` Nikolay Aleksandrovich Pavlov (ZyX)
@ 2017-01-18 20:30       ` Ray Andrews
  0 siblings, 0 replies; 6+ messages in thread
From: Ray Andrews @ 2017-01-18 20:30 UTC (permalink / raw)
  To: Nikolay Aleksandrovich Pavlov (ZyX), zsh-users

On 18/01/17 12:12 PM, Nikolay Aleksandrovich Pavlov (ZyX) wrote:
>
>
> Alternative solutions are using `typeset -m 'SMARTD*'` (you did know about `which -m`, did not you? This is similar.)

Perfect.  And yes, it's nice to see '-m' here behave as expected from 
'whence -m'.

English:
Though we would say: "didn't you?" and 'didn't' expands to 'did not', 
yet "did not you" is incorrect, which is quite crazy, it should be: "did 
you not?"  Probably no one can even explain why.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-01-18 20:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-18 16:13 this should be easy variable expansion including globs Ray Andrews
2017-01-18 18:46 ` Peter Stephenson
2017-01-18 19:51   ` Ray Andrews
2017-01-18 20:12     ` Nikolay Aleksandrovich Pavlov (ZyX)
2017-01-18 20:30       ` Ray Andrews
     [not found]     ` <484161484770354__27207.6165573255$1484770824$gmane$org@web26m.yandex.ru>
2017-01-18 20:20       ` Daniel Shahaf

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).