Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Most Recent File
- X-seq: zsh-users 27280
- From: "Paul" <GammaFunction@xxxxxxxxxxx>
- To: "Pier Paolo Grassi" <pierpaolog@xxxxxxxxx>, "Bart Schaefer" <schaefer@xxxxxxxxxxxxxxxx>
- Cc: "Vin Shelton" <acs@xxxxxxxxxxxxxxxxxxxx>, "Peter Stephenson" <p.w.stephenson@xxxxxxxxxxxx>, "Zsh-Users List" <zsh-users@xxxxxxx>
- Subject: Re: Most Recent File
- Date: Sat, 23 Oct 2021 19:32:09 -0500
- Archived-at: <https://zsh.org/users/27280>
- Dkim-filter: OpenDKIM Filter v2.11.0 smtp.vivaldi.net 436D9BD05F
- Dkim-filter: OpenDKIM Filter v2.11.0 smtp.vivaldi.net 3D4E4BD06B
- In-reply-to: <CAP+y1xC3Dx74sBaCf8mgmEcOMh+hUH6zAdt236k=JTjw4-cBqQ@mail.gmail.com>
- List-id: <zsh-users.zsh.org>
Fundamentally, you're dealing with a limitation of Zsh (and almost all
other shells): There is no way to "return" a list from a function.
$( ) captures stdout, which is a *stream*, not inherently a list or any
other structure. Using $( ) means you have to serialize your data, even
if only by putting NULs between each element:
recent(){
local l=( *(om[1,$1]) )
print -rn ${(pj:\0:)l}
}
ls -ld -- "${(0)$(recent 3)}"
There's an alternate convention in shell programming where results are
instead saved in a parameter, either of the user's choosing, or
sometimes hardcoded as 'reply'.
recent(){
# Use $reply if no parameter name given
typeset -ga "${2:=reply}"
set -A "$2" *(om[1,$1])
}
recent 3 files; ls -ld $files
This way, there's no serialization, forking, or reading and writing to
pipes.
On Sat Oct 23, 2021 at 7:24 PM CDT, Pier Paolo Grassi wrote:
> >That doesn't work because if one of the file names has a newline in
> >it, (f) will split it into two words. (Also I think you left out an
> >open paren.)
>
> sorry about that, I haven't ever considered newlines in filenames, since
> I
> wouldn't put them in the first place. Of course that's not to say that
> cannot happen anyway, of course.
> And yes, it should have been:
>
> ls "${(f)$(recent 3)}"
>
> thanks for catching that
>
> Pier Paolo Grassi
>
>
> Il giorno dom 24 ott 2021 alle ore 00:42 Bart Schaefer <
> schaefer@xxxxxxxxxxxxxxxx> ha scritto:
>
> > On Sat, Oct 23, 2021 at 1:57 PM Pier Paolo Grassi <pierpaolog@xxxxxxxxx>
> > wrote:
> > >
> > > and use it like this:
> > >
> > > ls "${(f)$recent 3)}"
> >
> > That doesn't work because if one of the file names has a newline in
> > it, (f) will split it into two words. (Also I think you left out an
> > open paren.)
> >
> > print -lr -- ${(q)f}
> >
> > and then
> >
> > eval ls -ld $(recent 3)
> >
> > seems to be the closest thing.
> >
> > > Il giorno sab 23 ott 2021 alle ore 22:44 Vin Shelton <
> > acs@xxxxxxxxxxxxxxxxxxxx> ha scritto:
> > >>
> > >> What am I doing wrong? Does quoting not work correctly in captured
> > output?
> >
> > The trouble is that "ls" doesn't interpret the quoting, when $(...)
> > preserves it. So you have to emit the quotes in a form that the shell
> > can interpret, and then use "eval" to make that happen.
> >
> > For extra safety, you could use ${(qqqq)f} instead.
> >
Messages sorted by:
Reverse Date,
Date,
Thread,
Author