Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Inconsistent behavior with comparisons and recursive glob patterns
- X-seq: zsh-workers 52911
- From: Alan Wagner-Krankel <awk@xxxxxxxxxxx>
- To: Eric Cook <llua@xxxxxxx>, zsh-workers@xxxxxxx
- Subject: Re: Inconsistent behavior with comparisons and recursive glob patterns
- Date: Wed, 1 May 2024 02:55:55 -0500
- Archived-at: <https://zsh.org/workers/52911>
- In-reply-to: <c97c8fe9-2f56-45b7-bfb2-9f2a97283859@gmx.com>
- List-id: <zsh-workers.zsh.org>
- References: <CAGZNKjL2cJhLopFPAFFTewh2cHxX+_L4vMx2Nf9bAS0ud58RBw@mail.gmail.com> <c97c8fe9-2f56-45b7-bfb2-9f2a97283859@gmx.com>
Thanks - I did miss that **/ wasn't supported in conditional expressions.
I wonder if there might be some value in making that explicit in the
documentation, possibly by changing the paragraph you referenced to
something like this:
Pattern metacharacters are active for the pattern arguments. The patterns
are the same as those used for filename generation, see zshexpn(1), but
there is no special behaviour of `/' nor initial dots, shorthand operators
such as **/ are not converted to their expanded forms, and glob qualifiers
are only allowed for forcing filenames to be generated as described above.
There's a slight issue that "such as **/" implies there are many
shorthand operators; I have no idea if there are any others besides
**/ and ***/.
Thanks,
Awk
On Tue, Apr 30, 2024 at 9:11 AM Eric Cook <llua@xxxxxxx> wrote:
>
> On 4/30/24 04:14, Alan Wagner-Krankel wrote:
> > The results of these conditional expressions using recursive glob
> > operators were unexpectedly different:
> >
> >> [[ f0 = **/f? ]] && print true || print false
> > false
> >> setopt extendedglob
> >> [[ f0 = (*/)#f? ]] && print true || print false
> > true
>
> A couple things about [[:
>
> ```
> Pattern metacharacters are active for the pattern arguments; the patterns are
> the same as those used for filename generation, see zshexpn(1), but there is
> no special behaviour of ‘/' nor initial dots, and no glob qualifiers are al‐
> lowed.
> ```
>
> That last bit about glob qualifiers is out of date since you can now use them to
> force filename generation on in [[. but the point is you aren't doing filename
> generation in [[ (by default), which is where **/ is shorthand for (*/)#.
> pattern matching/globbing is tightly coupled to filename generation in unix shells
> but there are difference.
>
> Even when you use a glob qualifier to force filename generation to happen, you
> still wasn't going to get the behavior you desired since the pattern would've
> underwent filename generation before the comparison that [['s =/== does.
>
> % (set -x; [[ f0 = **/f?(#qN) ]]; touch f2; [[ f0 = **/f?(#qN) ]])
> +zsh:3> [[ f0 = ]]
> +zsh:3> touch f2
> +zsh:3> [[ f0 = f2 ]]
>
> >
> > Since **/ is a shorthand version of (*/)#, it seems like they both
> > should have returned 'true'. The comparisons behave the same when
> > there is at least one directory in the path:
> >
> >> [[ d1/f1 = **/f? ]] && print true || print false
> > true
> >> setopt extendedglob
> >> [[ d1/f1 = (*/)#f? ]] && print true || print false
> > true
> >
> > I came across this because it affects the behavior of zmv, via a test
> > that filters filenames (line 254 in zsh5.9). An example:
> >
> >> mkdir d1 d1/d2
> >> touch f0 d1/f1 d1/d2/f2
> >> print -rl -- **/f?
> > d1/d2/f2
> > d1/f1
> > f0
> >> autoload zmv
> >> zmv -n '**/f?' '$f.txt'
> > mv -- d1/d2/f2 d1/d2/f2.txt
> > mv -- d1/f1 d1/f1.txt
> >> zmv -n '(*/)#f?' '$f.txt'
> > mv -- d1/d2/f2 d1/d2/f2.txt
> > mv -- d1/f1 d1/f1.txt
> > mv -- f0 f0.txt
> >
> > I think both zmv calls should have attempted to update the 'f0' file
> > in the base directory. Am I missing something?
> >
> > Thanks,
> > Awk
> >
> I'll leave zmv's implementation for someone else to answer but i suspect the reasoning is similar.
>
Messages sorted by:
Reverse Date,
Date,
Thread,
Author