zsh-users
 help / color / mirror / code / Atom feed
* Glob specifiers for intermediate path components
@ 2014-11-26 17:32 Jörg Ziefle
  2014-11-26 18:00 ` Mikael Magnusson
  0 siblings, 1 reply; 5+ messages in thread
From: Jörg Ziefle @ 2014-11-26 17:32 UTC (permalink / raw)
  To: zsh-users

Suppose I have the following directory structure:

$ mkdir a
$ touch a/1
$ ln -s a b
$ ls -ld a b a/1
drwxr-xr-x  3 jozi  staff  102 Nov 26 18:27 a
-rw-r--r--  1 jozi  staff    0 Nov 26 18:27 a/1
lrwxr-xr-x  1 jozi  staff    1 Nov 26 18:27 b -> a

Globbing for files within directories, I get the file within the
directory pointed by symlink b too:

$ print -l */*(.)
a/1
b/1

How can I restrict the globbing for the first directory level to
directories only, excluding symlinks to directories? The obvious
doesn't work:

$ print -l *(/)/*(.)
zsh: bad pattern: *(/)/*(.)

More generally, how can I specify glob qualifiers for intermediate
path components? In spirit:

$ print -l a(...)/b(...)/c(...)/d(...)/e(...)/f(...)

where (...) denotes glob qualifiers for the respective path components, or even:

$ print -l {{a(...)/b(...)}/c(...)}


Thanks,

Joerg


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

* Re: Glob specifiers for intermediate path components
  2014-11-26 17:32 Glob specifiers for intermediate path components Jörg Ziefle
@ 2014-11-26 18:00 ` Mikael Magnusson
  2014-11-27  1:52   ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Mikael Magnusson @ 2014-11-26 18:00 UTC (permalink / raw)
  To: Jörg Ziefle; +Cc: Zsh Users

On Wed, Nov 26, 2014 at 6:32 PM, Jörg Ziefle <joerg.ziefle@gmail.com> wrote:
> Suppose I have the following directory structure:
>
> $ mkdir a
> $ touch a/1
> $ ln -s a b
> $ ls -ld a b a/1
> drwxr-xr-x  3 jozi  staff  102 Nov 26 18:27 a
> -rw-r--r--  1 jozi  staff    0 Nov 26 18:27 a/1
> lrwxr-xr-x  1 jozi  staff    1 Nov 26 18:27 b -> a
>
> Globbing for files within directories, I get the file within the
> directory pointed by symlink b too:
>
> $ print -l */*(.)
> a/1
> b/1
>
> How can I restrict the globbing for the first directory level to
> directories only, excluding symlinks to directories? The obvious
> doesn't work:
>
> $ print -l *(/)/*(.)
> zsh: bad pattern: *(/)/*(.)
>
> More generally, how can I specify glob qualifiers for intermediate
> path components? In spirit:
>
> $ print -l a(...)/b(...)/c(...)/d(...)/e(...)/f(...)
>
> where (...) denotes glob qualifiers for the respective path components, or even:
>
> $ print -l {{a(...)/b(...)}/c(...)}

You can't, as such. There are at least two workarounds I can think of.

print -l a(/e:'REPLY=$REPLY/b(/)':)
(this one quickly gets messy to nest)

() { print -l $^@/b(/) } a(/)
() { () { print -l $^@/c(/) } $^@/b(/) } a(/)
You may need to add N in the glob quals here too, or intermediate
directories with no children would produce a glob error.

Note more specifically also that **/*(.) does not recurse through
symlinks to directories, ***/*(.) would.

-- 
Mikael Magnusson


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

* Re: Glob specifiers for intermediate path components
  2014-11-26 18:00 ` Mikael Magnusson
@ 2014-11-27  1:52   ` Bart Schaefer
  2014-11-27  4:27     ` Jörg Ziefle
  0 siblings, 1 reply; 5+ messages in thread
From: Bart Schaefer @ 2014-11-27  1:52 UTC (permalink / raw)
  To: Zsh Users

On Nov 26,  7:00pm, Mikael Magnusson wrote:
}
} > More generally, how can I specify glob qualifiers for intermediate
} > path components? In spirit:
} >
} > $ print -l a(...)/b(...)/c(...)/d(...)/e(...)/f(...)
} 
} You can't, as such. There are at least two workarounds I can think of.

A third would be something like this:

    glueglob() {
      emulate -R zsh -o csh_null_glob
      local here there
      while (( ARGC ))
      do
	here=( $^here$~1 )
	here=( ${^here}${2:+/} )
	shift
      done
      print $here
    }
    print -l $( noglob glueglob a(...) b(...) c(...) d(...) e(...) f(...) )

There's almost certainly a fancy expression that could be written to
split a(...)/b(...)/c(...)/d(...)/e(...)/f(...) on the slashes without
being confused by the (/) glob qualifier, but I'm not going to attempt
to write it tonight.


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

* Re: Glob specifiers for intermediate path components
  2014-11-27  1:52   ` Bart Schaefer
@ 2014-11-27  4:27     ` Jörg Ziefle
  2014-11-27  5:46       ` Bart Schaefer
  0 siblings, 1 reply; 5+ messages in thread
From: Jörg Ziefle @ 2014-11-27  4:27 UTC (permalink / raw)
  To: zsh-users

On Thu, Nov 27, 2014 at 2:52 AM, Bart Schaefer
<schaefer@brasslantern.com> wrote:

> A third would be something like this:
>
>     glueglob() {
>       emulate -R zsh -o csh_null_glob
>       local here there
>       while (( ARGC ))
>       do
>         here=( $^here$~1 )
>         here=( ${^here}${2:+/} )
>         shift
>       done
>       print $here
>     }
>     print -l $( noglob glueglob a(...) b(...) c(...) d(...) e(...) f(...) )

Works like a charm, thank you!

> There's almost certainly a fancy expression that could be written to
> split a(...)/b(...)/c(...)/d(...)/e(...)/f(...) on the slashes without
> being confused by the (/) glob qualifier, but I'm not going to attempt
> to write it tonight.

In Perl, it could look like:

$ perl -e '$_="a(.)/b(@)/c(/N)/d(*)/e(@)/f/g/h/i(/)"; while
(m{((.*?)(\(.*?\))?)(/|$)}g) { print "CHF 0.96\n" }'
a(.)
b(@)
c(/N)
d(*)
e(@)
f
g
h
i(/)

Not sure whether this solution is waterproof though.

Joerg


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

* Re: Glob specifiers for intermediate path components
  2014-11-27  4:27     ` Jörg Ziefle
@ 2014-11-27  5:46       ` Bart Schaefer
  0 siblings, 0 replies; 5+ messages in thread
From: Bart Schaefer @ 2014-11-27  5:46 UTC (permalink / raw)
  To: zsh-users

On Nov 27,  5:27am, Jorg Ziefle wrote:
} Subject: Re: Glob specifiers for intermediate path components
}
} On Thu, Nov 27, 2014 at 2:52 AM, Bart Schaefer
} > split a(...)/b(...)/c(...)/d(...)/e(...)/f(...) on the slashes without
} > being confused by the (/) glob qualifier
} 
} $ perl -e '$_="a(.)/b(@)/c(/N)/d(*)/e(@)/f/g/h/i(/)"; while
} (m{((.*?)(\(.*?\))?)(/|$)}g) { print "$1\n" }'

It probably doesn't have to be that grotty ... just split on ")/" and
then patch up the lost close parens, for example.  Yes, you can come
up with a convoluted qualifier that has ")/" embedded in it, so it
wouldn't be perfect, but it'd cover 99+% of interactive use.


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

end of thread, other threads:[~2014-11-27  5:47 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-26 17:32 Glob specifiers for intermediate path components Jörg Ziefle
2014-11-26 18:00 ` Mikael Magnusson
2014-11-27  1:52   ` Bart Schaefer
2014-11-27  4:27     ` Jörg Ziefle
2014-11-27  5:46       ` Bart Schaefer

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