zsh-users
 help / color / mirror / code / Atom feed
* autoload variables
@ 2021-08-30 15:22 Anthony Fletcher
  2021-08-30 15:41 ` Roman Perepelitsa
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Anthony Fletcher @ 2021-08-30 15:22 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 497 bytes --]

Hi

We can autoload functions but is there a way to autoload variables?

My .zshenv and .zshrc files are getting longer and slower with more lists
of exported variables that are useful but only needed in a few
sessions. For instance, one variable is to identify the default uplink
interface

   export UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //; s/
.*// p;q' )

Useful when I'm debugging the network but not needed otherwise.

Can I autoload these variables as needed?

   Anthony.

[-- Attachment #2: Type: text/html, Size: 681 bytes --]

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

* Re: autoload variables
  2021-08-30 15:22 autoload variables Anthony Fletcher
@ 2021-08-30 15:41 ` Roman Perepelitsa
  2021-08-30 16:40 ` René Neumann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Roman Perepelitsa @ 2021-08-30 15:41 UTC (permalink / raw)
  To: Anthony Fletcher; +Cc: Zsh Users

On Mon, Aug 30, 2021 at 5:23 PM Anthony Fletcher <anthony@bifb.org> wrote:
>
> We can autoload functions but is there a way to autoload variables?
>
> My .zshenv and .zshrc files are getting longer and slower with more lists of exported variables that are useful but only needed in a few sessions. For instance, one variable is to identify the default uplink interface
>
>    export UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q' )
>
> Useful when I'm debugging the network but not needed otherwise.
>
> Can I autoload these variables as needed?

Zsh doesn't know which commands respect UPIF environment variable, so
if it supported autoloadable environment variables it would have to
autoload all of them when you run the first command. Hardly an
improvement over your current setup.

If you know which commands respect UPIF (I'll use foobar because I
don't know), you can try this:

  alias foobar='env UPIF=${UPIF-${UPIF::=$(ip -4 r | ...)}} foobar'

This will compute UPIF on the first invocation and remember the value
for the duration of the current zsh session.

This can be generalized so that you could do this in zshrc:

  # Define how UPIF and BLAH environment variables are computed.
  function lazy-env-UPIF() ip -4 r | sed ...
  function lazy-env-BLAH() print 42

  # Declare that foobar command needs UPIF and BLAH environment variables.
  cmd-needs-env foobar UPIF BLAH

Roman.


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

* Re: autoload variables
  2021-08-30 15:22 autoload variables Anthony Fletcher
  2021-08-30 15:41 ` Roman Perepelitsa
@ 2021-08-30 16:40 ` René Neumann
  2021-08-30 16:57   ` Anthony Fletcher
  2021-08-30 16:49 ` Bart Schaefer
  2021-08-31 20:37 ` Marc Chantreux
  3 siblings, 1 reply; 20+ messages in thread
From: René Neumann @ 2021-08-30 16:40 UTC (permalink / raw)
  To: Anthony Fletcher, zsh-users

Am 30.08.21 um 17:22 schrieb Anthony Fletcher:
> For instance, one variable is to identify the default uplink
> interface
> 
>     export UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //; s/
> .*// p;q' )
> 
> Useful when I'm debugging the network but not needed otherwise.

Is there a reason you need this as a variable? Would a function

upif() { ip -4 r | ... }

not suffice?

- René


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

* Re: autoload variables
  2021-08-30 15:22 autoload variables Anthony Fletcher
  2021-08-30 15:41 ` Roman Perepelitsa
  2021-08-30 16:40 ` René Neumann
@ 2021-08-30 16:49 ` Bart Schaefer
  2021-08-31 20:37 ` Marc Chantreux
  3 siblings, 0 replies; 20+ messages in thread
From: Bart Schaefer @ 2021-08-30 16:49 UTC (permalink / raw)
  To: Anthony Fletcher; +Cc: Zsh Users

On Mon, Aug 30, 2021 at 8:22 AM Anthony Fletcher <anthony@bifb.org> wrote:
>
> Can I autoload these variables as needed?

It would require at least as much overhead to record when and from
where to load the variables as it does to have them defined.

Related to what Roman suggested, you coud also place the variables in
ordinary autoload functions that you run when you need to initialize
them.  Use e.g.

typeset -gx UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //;
s/ .*// p;q' )

to have the variable become a global export instead of locals.


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

* Re: autoload variables
  2021-08-30 16:40 ` René Neumann
@ 2021-08-30 16:57   ` Anthony Fletcher
  2021-08-30 19:30     ` Mikael Magnusson
  2021-08-30 21:34     ` René Neumann
  0 siblings, 2 replies; 20+ messages in thread
From: Anthony Fletcher @ 2021-08-30 16:57 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 842 bytes --]

On Mon, 30 Aug 2021 at 12:40, René Neumann <lists@necoro.eu> wrote:

> Am 30.08.21 um 17:22 schrieb Anthony Fletcher:
> > For instance, one variable is to identify the default uplink
> > interface
> >
> >     export UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //; s/
> > .*// p;q' )
> >
> > Useful when I'm debugging the network but not needed otherwise.
>
> Is there a reason you need this as a variable? Would a function
>
> upif() { ip -4 r | ... }
>
> not suffice?
>
> - René
>

A function would work but then you need to run it every time to get the
same value..... and of course the variable is for other commands. Thus
       systemcommand $(upif)
In this particular case anything to do with the uplink interface (eg
dump_dhcp6). I guess the function could cache the result for speed.

Anthony.

[-- Attachment #2: Type: text/html, Size: 1280 bytes --]

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

* Re: autoload variables
  2021-08-30 16:57   ` Anthony Fletcher
@ 2021-08-30 19:30     ` Mikael Magnusson
  2021-08-30 21:34     ` René Neumann
  1 sibling, 0 replies; 20+ messages in thread
From: Mikael Magnusson @ 2021-08-30 19:30 UTC (permalink / raw)
  To: Anthony Fletcher; +Cc: zsh-users

On 8/30/21, Anthony Fletcher <anthony@bifb.org> wrote:
> On Mon, 30 Aug 2021 at 12:40, René Neumann <lists@necoro.eu> wrote:
>
>> Am 30.08.21 um 17:22 schrieb Anthony Fletcher:
>> > For instance, one variable is to identify the default uplink
>> > interface
>> >
>> >     export UPIF=$(ip -4 r | sed -n -e '/^default/ s/^default.*dev //;
>> > s/
>> > .*// p;q' )
>> >
>> > Useful when I'm debugging the network but not needed otherwise.
>>
>> Is there a reason you need this as a variable? Would a function
>>
>> upif() { ip -4 r | ... }
>>
>> not suffice?
>>
>> - René
>>
>
> A function would work but then you need to run it every time to get the
> same value..... and of course the variable is for other commands. Thus
>        systemcommand $(upif)
> In this particular case anything to do with the uplink interface (eg
> dump_dhcp6). I guess the function could cache the result for speed.

It's unclear from your examples if these variables actually need to be
in the environment (eg, used by the program automatically), or if
you're naming them on the command line (eg, some_cmd $myvars). In the
latter case, they don't need to be exported at all.

This may be an unpopular suggestion (I would also not use it :)), but
you can abuse global aliases in the latter case as well, if you are
very opposed to typing $(foo) instead of $FOO:
% alias -g '$UPIF=$(echo 123.12.2.15)'
% echo $UPIF
123.12.2.15

(keep in mind the word needs to appear separate from other words and
exactly as specified for this to work, eg not foo$UPIF or ${UPIF}).
(You also don't need the $ at all if you do this, so you could just
call it UPIF too, assuming you don't use this in the literal sense
(although if you did, you could write \UPIF in those cases).).

If you *do* need these in the environment, and assuming that they
don't change very often, you could initialize all of them in .zprofile
instead of .zshrc and they will just persist in your environment at no
extra startup cost. (You can do this for the latter case too,
actually).

-- 
Mikael Magnusson


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

* Re: autoload variables
  2021-08-30 16:57   ` Anthony Fletcher
  2021-08-30 19:30     ` Mikael Magnusson
@ 2021-08-30 21:34     ` René Neumann
  2021-08-30 21:46       ` Bart Schaefer
  1 sibling, 1 reply; 20+ messages in thread
From: René Neumann @ 2021-08-30 21:34 UTC (permalink / raw)
  To: zsh-users

Am 30.08.21 um 18:57 schrieb Anthony Fletcher:
> On Mon, 30 Aug 2021 at 12:40, René Neumann <lists@necoro.eu> wrote:
>>
>> Is there a reason you need this as a variable? Would a function
>>
>> upif() { ip -4 r | ... }
>>
>> not suffice?
>>
>> - René
>>
> 
> A function would work but then you need to run it every time to get the
> same value..... and of course the variable is for other commands. Thus
>         systemcommand $(upif)
> In this particular case anything to do with the uplink interface (eg
> dump_dhcp6). I guess the function could cache the result for speed.
> 

As always: the tradeoff between having everything loaded "just in case" 
vs the "doing extra work when I need it".

In my eyes, it heavily depends on the use cases: When you write, "I need 
it (only) when debugging networks", I hear "once in a blue moon" and 
would argue that any discussion about speed is wasted time (i.e. well, 
let it recalc the value each of the four times a month one needs it).
But you also might be someone for whom "debugging networks" is part of 
the job, which of course shifts the focus a lot...


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

* Re: autoload variables
  2021-08-30 21:34     ` René Neumann
@ 2021-08-30 21:46       ` Bart Schaefer
  2021-08-31  0:10         ` Anthony Fletcher
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Schaefer @ 2021-08-30 21:46 UTC (permalink / raw)
  To: René Neumann; +Cc: Zsh Users

On Mon, Aug 30, 2021 at 2:34 PM René Neumann <lists@necoro.eu> wrote:
>
> As always: the tradeoff between having everything loaded "just in case"
> vs the "doing extra work when I need it".

As Roman said, "Zsh doesn't know which commands respect UPIF
environment variable".  If you can easily enumerate them, you could
write

function $(list of commands using UPIF) {
  export UPIF=$(....)
  unfunction $(list of commands using UPIF)
  command $0 "$@"
}

This could be combined with autoloading to keep the function bodies
out of shell memory until one of them is executed.


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

* Re: autoload variables
  2021-08-30 21:46       ` Bart Schaefer
@ 2021-08-31  0:10         ` Anthony Fletcher
  2021-08-31 18:11           ` Roman Perepelitsa
  0 siblings, 1 reply; 20+ messages in thread
From: Anthony Fletcher @ 2021-08-31  0:10 UTC (permalink / raw)
  To: Zsh Users

[-- Attachment #1: Type: text/plain, Size: 1332 bytes --]

On Mon, 30 Aug 2021 at 17:46, Bart Schaefer <schaefer@brasslantern.com>
wrote:

> On Mon, Aug 30, 2021 at 2:34 PM René Neumann <lists@necoro.eu> wrote:
> >
> > As always: the tradeoff between having everything loaded "just in case"
> > vs the "doing extra work when I need it".
>
> As Roman said, "Zsh doesn't know which commands respect UPIF
> environment variable".  If you can easily enumerate them, you could
> write
>
> function $(list of commands using UPIF) {
>   export UPIF=$(....)
>   unfunction $(list of commands using UPIF)
>   command $0 "$@"
> }
>
> This could be combined with autoloading to keep the function bodies
> out of shell memory until one of them is executed.
>
>
Thanks everyone for the suggestions.

Yes - I'm often a "jack of all trades". I debug networks more often than
I'd like and then off to work on something else. But it's always a balance
to remember the recipe to eval  whatever variable is standard for that
command on that Linux system in that VLAN. Easier to have them all in my
zsh rc files but it slows everything down.

I think that using a function that caches the value and then invoked via
$(upif) is easiest. Something like
 upif () { export UPIF; echo ${UPIF:=$(ip r | ....) }}
 tcpdump -i $(upif) .......

Lots of good ideas. Thanks

Anthony.

[-- Attachment #2: Type: text/html, Size: 1898 bytes --]

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

* Re: autoload variables
  2021-08-31  0:10         ` Anthony Fletcher
@ 2021-08-31 18:11           ` Roman Perepelitsa
  2021-08-31 19:16             ` Bart Schaefer
  0 siblings, 1 reply; 20+ messages in thread
From: Roman Perepelitsa @ 2021-08-31 18:11 UTC (permalink / raw)
  To: Anthony Fletcher; +Cc: Zsh Users

On Tue, Aug 31, 2021 at 2:11 AM Anthony Fletcher <anthony@bifb.org> wrote:
>
> I think that using a function that caches the value and then invoked via $(upif) is easiest. Something like
>
>    upif () { export UPIF; echo ${UPIF:=$(ip r | ....) }}
>    tcpdump -i $(upif) .......

Assuming that you don't set UPIF manually anywhere else, this code is
equivalent to this:

  upif() { ip r | ....}
  tcpdump -i $(upif) .......

That export and conditional assignment don't do anything because they
are within a subshell. Anything you export there gets wiped out
immediately and won't be used the next time you invoke $(upif).

Roman.


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

* Re: autoload variables
  2021-08-31 18:11           ` Roman Perepelitsa
@ 2021-08-31 19:16             ` Bart Schaefer
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Schaefer @ 2021-08-31 19:16 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Anthony Fletcher, Zsh Users

On Tue, Aug 31, 2021 at 11:12 AM Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>
> That export and conditional assignment don't do anything because they
> are within a subshell. Anything you export there gets wiped out

So an alternative would be

upif () { export UPIF=${UPIF:=$(ip r | ....) }}
upif && tcpdump -i $UPIF .......


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

* Re: autoload variables
  2021-08-30 15:22 autoload variables Anthony Fletcher
                   ` (2 preceding siblings ...)
  2021-08-30 16:49 ` Bart Schaefer
@ 2021-08-31 20:37 ` Marc Chantreux
  2021-08-31 21:03   ` Roman Perepelitsa
  3 siblings, 1 reply; 20+ messages in thread
From: Marc Chantreux @ 2021-08-31 20:37 UTC (permalink / raw)
  To: Anthony Fletcher; +Cc: zsh-users

hello zsh users,

> We can autoload functions but is there a way to autoload variables?

i was hoping for a better answer than mine (reading this list provides
me so many "wow" moments). the way i dealt years ago to deal with my
"too heavy .zshenv" is to write what i call "modules"

<<\. cat > /usr/local/bin/mynetstuff.zsh
# yes i use setopt pathdirs :)

export IFUP=$( ip -4 r |sed ...)

mynetstuff/thing () { ... }
mynetstuff/stuff () { ... }
.

now i can run

. mynetstuff.zsh

when i need my net stuff.  to unload functions, you can write

    unset 'functions['$^functions[(I)mynetstuff/*]']'

oth.

besides: if the sed command is for real, i'm curious about
how it works:

    sed -n -e '/^default/ s/^default.*dev //; s/ > .*// p;q'

my guess is it is equivalent to

    sed -r '/^default dev (\S+) .*/!d; s//\1/; q'

or

    ip -4 r | sed -r '/^default dev /!d; s///; s/ .*//; q'

but as you quit anyway, i assume you *know* that what you need is on the
first line so this should do the job:

    ip -4 r | head -n1 | cut -d' ' -f3

regards,
marc


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

* Re: autoload variables
  2021-08-31 20:37 ` Marc Chantreux
@ 2021-08-31 21:03   ` Roman Perepelitsa
  2021-09-01  8:29     ` Marc Chantreux
  0 siblings, 1 reply; 20+ messages in thread
From: Roman Perepelitsa @ 2021-08-31 21:03 UTC (permalink / raw)
  To: Marc Chantreux; +Cc: Anthony Fletcher, Zsh Users

On Tue, Aug 31, 2021 at 10:38 PM Marc Chantreux <eiro@phear.org> wrote:
>
> besides: if the sed command is for real, i'm curious about
> how it works

The original sed command from the first email:

  sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q'

It's equivalent to this:

  head -1 | sed 's/^default.*dev //' | sed 's/ .*//'

In plain English:

  1. Take the first line.
  2. If a portion of the line matches '^default.*dev', remove it:
  3. If a portion of the line matches ' .*', remove it.

Roman.


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

* Re: autoload variables
  2021-08-31 21:03   ` Roman Perepelitsa
@ 2021-09-01  8:29     ` Marc Chantreux
  2021-09-01  9:51       ` Roman Perepelitsa
  0 siblings, 1 reply; 20+ messages in thread
From: Marc Chantreux @ 2021-09-01  8:29 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Anthony Fletcher, Zsh Users

Hi Roman,

Le Tue, Aug 31, 2021 at 11:03:39PM +0200, Roman Perepelitsa a écrit :
>   sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q'

> In plain English:

english is fine. can you confirm that '/^default/ s/^default.*dev //'
is a suttered way to say              's/^default.*dev //' ?

>   2. If a portion of the line matches '^default.*dev', remove it

i realize i assumed in the first place that 'default dev' was the only
valid part but i just saw there can be a 'via something' subpart.

>   1. Take the first line.

that's what i was afraid about. does ip r garanty that? my version was

sed '
    /^default.*dev /!d # do nothing until you find a match
    # so the next commands applies only on the valid line
    s///d              # remove what you just found
    s/ .*//d           # remove the tail of the sentence
    q                  # print and quit
'

Regards
marc


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

* Re: autoload variables
  2021-09-01  8:29     ` Marc Chantreux
@ 2021-09-01  9:51       ` Roman Perepelitsa
  2021-09-01 10:06         ` Marc Chantreux
  2021-09-02 23:09         ` Anthony Fletcher
  0 siblings, 2 replies; 20+ messages in thread
From: Roman Perepelitsa @ 2021-09-01  9:51 UTC (permalink / raw)
  To: Marc Chantreux; +Cc: Anthony Fletcher, Zsh Users

On Wed, Sep 1, 2021 at 10:30 AM Marc Chantreux <eiro@phear.org> wrote:
>
> Hi Roman,
>
> Le Tue, Aug 31, 2021 at 11:03:39PM +0200, Roman Perepelitsa a écrit :
> >   sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q'
>
> > In plain English:
>
> english is fine. can you confirm that '/^default/ s/^default.*dev //'
> is a suttered way to say              's/^default.*dev //' ?

Yes, these are equivalent. Anything that matches '^default.*dev '
matches '^default'.

> that's what i was afraid about. does ip r garanty that?

I don't know. FWIW, I'd do it like this:

    ip -j -4 r | jq -r '.[] | select(.dst == "default") | .dev'

This requires a new-enough version of ip to support json output.

Roman.


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

* Re: autoload variables
  2021-09-01  9:51       ` Roman Perepelitsa
@ 2021-09-01 10:06         ` Marc Chantreux
  2021-09-01 13:52           ` Bart Schaefer
  2021-09-02 23:09         ` Anthony Fletcher
  1 sibling, 1 reply; 20+ messages in thread
From: Marc Chantreux @ 2021-09-01 10:06 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Anthony Fletcher, Zsh Users

> I don't know. FWIW, I'd do it like this:
>     ip -j -4 r | jq -r '.[] | select(.dst == "default") | .dev'

jq is a cool query langage over a arguable serialization system.
i'm waiting for cbor to replace json the way json replaced xml :)

thanks for your answer.
marc



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

* Re: autoload variables
  2021-09-01 10:06         ` Marc Chantreux
@ 2021-09-01 13:52           ` Bart Schaefer
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Schaefer @ 2021-09-01 13:52 UTC (permalink / raw)
  To: Marc Chantreux; +Cc: Roman Perepelitsa, Anthony Fletcher, Zsh Users

On Wed, Sep 1, 2021 at 3:06 AM Marc Chantreux <eiro@phear.org> wrote:
>
> i'm waiting for cbor to replace json the way json replaced xml :)

Off-topic opinion:  That will never happen.  JSON replaced XML because
JSON is directly interpretable in a widely-available programming
language without use of extra decoding, while still being readable as
plain text.  Nothing that uses a binary format will dislodge that
except in specialty applications.


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

* Re: autoload variables
  2021-09-01  9:51       ` Roman Perepelitsa
  2021-09-01 10:06         ` Marc Chantreux
@ 2021-09-02 23:09         ` Anthony Fletcher
  2021-09-03  0:07           ` Bart Schaefer
  2021-09-03  6:52           ` Marc Chantreux
  1 sibling, 2 replies; 20+ messages in thread
From: Anthony Fletcher @ 2021-09-02 23:09 UTC (permalink / raw)
  To: Roman Perepelitsa; +Cc: Marc Chantreux, Zsh Users

On 01 Sep 2021 at 11:51:30, Roman Perepelitsa wrote:
> On Wed, Sep 1, 2021 at 10:30 AM Marc Chantreux <eiro@phear.org> wrote:
> >
> > Hi Roman,
> >
> > Le Tue, Aug 31, 2021 at 11:03:39PM +0200, Roman Perepelitsa a écrit :
> > >   sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q'
> >
> > > In plain English:
> >
> > english is fine. can you confirm that '/^default/ s/^default.*dev //'
> > is a suttered way to say              's/^default.*dev //' ?
> 
> Yes, these are equivalent. Anything that matches '^default.*dev '
> matches '^default'.

Yes but the point is I am only interested in lines that start with
'default via'. I am ignoring all the other lines. Without the initial
match /^default/ all the other lines are processed by the
substitutions and I get the wrong interface.

> > that's what i was afraid about. does ip r garanty that?
> 
> I don't know. FWIW, I'd do it like this:
> 
>     ip -j -4 r | jq -r '.[] | select(.dst == "default") | .dev'
> 
> This requires a new-enough version of ip to support json output.

Cool - I didn't know JSON output was an option. Not that jq is much less
baroque than sed.  I think this is better than my sed script.

One point in favour of sed - it's then on all systems, jq isn't.

Sorry for the off-topic discussion.

		Anthony.



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

* Re: autoload variables
  2021-09-02 23:09         ` Anthony Fletcher
@ 2021-09-03  0:07           ` Bart Schaefer
  2021-09-03  6:52           ` Marc Chantreux
  1 sibling, 0 replies; 20+ messages in thread
From: Bart Schaefer @ 2021-09-03  0:07 UTC (permalink / raw)
  To: Roman Perepelitsa, Marc Chantreux, Zsh Users

On Thu, Sep 2, 2021 at 4:10 PM Anthony Fletcher <anthony@bifb.org> wrote:
>
> > > >   sed -n -e '/^default/ s/^default.*dev //; s/ .*// p;q'

To start out with, if this is GNU sed, that trailing ";q" means that
at most one line will be processed, and then sed will stop.  So this
is going to print either one or zero lines.  One line will be printed
if s/ .*//p matches the first line of input, otherwise nothing will
be.

In front of that, /^default/ means to consider lines that begin with
default as candidates for s/^default.*dev// -- but lines that don't
match /^default/ also won't have anything changed by that s///, so
either it should move on to the s///p and then q(uit).

> Yes but the point is I am only interested in lines that start with
> 'default via'. I am ignoring all the other lines. Without the initial
> match /^default/ all the other lines are processed by the
> substitutions and I get the wrong interface.

If that's true, then you have not accurately copy-pasted your sed
command in the original example.

If the command were this:

sed -n -e '/^default/{s/^default.*dev //; s/ .*// p;q;}'

Then the braces group the expressions that are separated by
semicolons, and you'll skip every line up to the first one that
matches /^default/ and then apply the two s/// to that before quitting
(again with exactly one or zero lines of output).  In that instance
the leading /^default/ matters.


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

* Re: autoload variables
  2021-09-02 23:09         ` Anthony Fletcher
  2021-09-03  0:07           ` Bart Schaefer
@ 2021-09-03  6:52           ` Marc Chantreux
  1 sibling, 0 replies; 20+ messages in thread
From: Marc Chantreux @ 2021-09-03  6:52 UTC (permalink / raw)
  To: Roman Perepelitsa, Zsh Users

> > > Le Tue, Aug 31, 2021 at 11:03:39PM +0200, Roman Perepelitsa a écrit :
> > > english is fine. can you confirm that '/^default/ s/^default.*dev //'
> > > is a suttered way to say              's/^default.*dev //' ?
> > 
> > Yes, these are equivalent. Anything that matches '^default.*dev '
> > matches '^default'.
> 
> Yes but the point is I am only interested in lines that start with
> 'default via'. I am ignoring all the other lines. Without the initial
> match /^default/ all the other lines are processed by the
> substitutions and I get the wrong interface.

there is no point of repeating yourself without leaving the lhs part
empty. What you just wrote is

* find default at the begin of the line
* find it *again then let's substitute something containing default

if you wanted to ignore a line, your sed script miss the d command
(i used it in the version i proposed):

    /^default/d
        stop the processing of this line (including the default p ending)
        if it match.
    /^default/!d
        stop the processing of this line (including the default p ending)
        if *don't* match.

also: sed keeps the track of its last match which can be called with an
empty lhs. so:

    /^default.*dev/!d ; s///

means:
* don't process the lines that don't match the pattern
* as it matched, remove the matched part

> > This requires a new-enough version of ip to support json output.
> Cool - I didn't know JSON output was an option. Not that jq is much less
> baroque than sed.  I think this is better than my sed script.

* sed is for text.
* jq is for datastructures serialized in json (i wish there will be a
  cbor backend at some point).

> One point in favour of sed - it's then on all systems, jq isn't.

sed is made to be a simple tool inside a pipe or from an editor: it
completes an ecosystem.

jq is a good query langage (baroque as well) but just for json.

> Sorry for the off-topic discussion.

this is my "fault" as i was the one who asked for your sed command.
To me this isn't off-topic at all: zsh is about gluing commands
and sed is both powerful and popular enough so any zsh user should
know a bit of sed.

regards
marc


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

end of thread, other threads:[~2021-09-03  6:53 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-30 15:22 autoload variables Anthony Fletcher
2021-08-30 15:41 ` Roman Perepelitsa
2021-08-30 16:40 ` René Neumann
2021-08-30 16:57   ` Anthony Fletcher
2021-08-30 19:30     ` Mikael Magnusson
2021-08-30 21:34     ` René Neumann
2021-08-30 21:46       ` Bart Schaefer
2021-08-31  0:10         ` Anthony Fletcher
2021-08-31 18:11           ` Roman Perepelitsa
2021-08-31 19:16             ` Bart Schaefer
2021-08-30 16:49 ` Bart Schaefer
2021-08-31 20:37 ` Marc Chantreux
2021-08-31 21:03   ` Roman Perepelitsa
2021-09-01  8:29     ` Marc Chantreux
2021-09-01  9:51       ` Roman Perepelitsa
2021-09-01 10:06         ` Marc Chantreux
2021-09-01 13:52           ` Bart Schaefer
2021-09-02 23:09         ` Anthony Fletcher
2021-09-03  0:07           ` Bart Schaefer
2021-09-03  6:52           ` Marc Chantreux

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).