zsh-users
 help / color / mirror / code / Atom feed
* difference between ~ & ^ negation
@ 2014-01-01 15:28 zzapper
  2014-01-01 21:44 ` Bart Schaefer
       [not found] ` <8lp61n01B02mHnv01lp8uc>
  0 siblings, 2 replies; 15+ messages in thread
From: zzapper @ 2014-01-01 15:28 UTC (permalink / raw)
  To: zsh-users

ls -lt **/*~*vssver.scc(.om[1,20])  # excluding vssver.scc 
ls -lt **/*.{js,php,css}~(libs|tmp|temp|test)/* # exclude directories from 
ls   EXTENDED_GLOB required

ls -lt **/^vssver.scc(.om[1,20])    #  excluding vssver.scc (simpler) 
ls -lt **/^(vssver.scc|*.ini)(.om[1,20]) # excluding vssver and any *.ini 

What are the advantages/differences between the two types of "ignore" ^ ~

zzapper

---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com



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

* Re: difference between ~ & ^ negation
  2014-01-01 15:28 difference between ~ & ^ negation zzapper
@ 2014-01-01 21:44 ` Bart Schaefer
  2014-01-02 21:01   ` Peter Stephenson
       [not found] ` <8lp61n01B02mHnv01lp8uc>
  1 sibling, 1 reply; 15+ messages in thread
From: Bart Schaefer @ 2014-01-01 21:44 UTC (permalink / raw)
  To: zsh-users

On Jan 1,  3:28pm, zzapper wrote:
>
> What are the advantages/differences between the two types of "ignore" ^ ~

The ^ operator is similar to *~ except that it has high precedence, so
the pattern following ^ (up to a slash) is excluded from the set of all
files in the same level of directory hierarchy; e.g. foo/^bar/baz looks
for baz in any subdirectory of foo except the subdirectory named bar.
Therefore the pattern may not contain a slash.

The ~ operator is very low precedence, so the entire directory search
(including descent into subdirectories) to the left of the tilde is
performed, and the pattern to the right of the tilde is tested against
each file or directory to exclude it from the final result.  This means
that the pattern to the right of the tilde is not actually a glob; a
wildcard in that pattern can match a slash in the tested name, and the
pattern may contain slashes.

Thus X~Z is nearly equivalent to X(e:'[[ $REPLY == Z ]] && reply=():').

To see advantages and disadvantages, consider two of your examples:

> ls -lt **/*~*vssver.scc(.om[1,20])  # excluding vssver.scc 
> ls -lt **/^vssver.scc(.om[1,20])    #  excluding vssver.scc (simpler) 

As you pointed out, the second case is simpler.  However, these are not
quite equivalent; the first one should be:

    ls -lt **/*~*/vssver.scc(.om[1,20])

Otherwise you also ignore "OLDvssver.scc" (for example), so the second
case is also easier to use correctly.  I find the most difficult thing
to remember about ~ is that actual globbing happens only on the left,
so the right side has to match the path names as simple strings.

On the other hand, suppose you want to ignore vssver.scc only in the
myproject subdirectory, but include it everywhere else:

    ls -lt **/*~*/myproject/vssver.scc

There's no way to express this with the ^ operator except by using two
globs and a qualifier:

    ls -lt **/^vssver.scc **/^myproject/vssver.scc(N)

(The qualifier avoids a "no match" error if there is no vssver.scc file
anywhere outside of myproject.)

Now suppose you want everything that's neither in myproject nor named
vssver.scc; these should all be equivalent:

    ls -lt **/^myproject/^vssver.scc
    ls -lt **/*~*/(myproject/*|vssver.scc)
    ls -lt **/^vssver.scc~*/myproject/*

But these next two are not, do you see why?

    ls -lt **/^myproject~*/vssver.scc
    ls -lt **/^myproject/*~*/vssver.scc

Important note: ^ is special only in cases where / is special (globs).


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

* Re: difference between ~ & ^ negation
  2014-01-01 21:44 ` Bart Schaefer
@ 2014-01-02 21:01   ` Peter Stephenson
  2014-01-02 21:36     ` Bart Schaefer
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 2014-01-02 21:01 UTC (permalink / raw)
  To: zsh-users

On Wed, 01 Jan 2014 13:44:59 -0800
Bart Schaefer <schaefer@brasslantern.com> wrote:
> Important note: ^ is special only in cases where / is special (globs).

That's not true...

setopt extendedglob
[[ foo = ^foo ]] || print foo actually is foo
[[ bar = ^foo ]] && print but bar is not foo

"^" is still special here; the difference is that if a "/" appeared
after it *that* wouldn't be special in this context, i.e. the effect of
the "^" would extend to the end of the context (next closing parenthesis
or end of string).  However, that's the normal behaviour of operators
--- only ~ extends over "/"s in file context.  As the FAQ says,

  Note that `~' is the only globbing operator to have a lower
  precedence than `/'.  For example, `**/foo~*bar*' matches any
  file in a subdirectory called `foo', except where `bar'
  occurred somewhere in the path (e.g. `users/barstaff/foo' will
  be excluded by the `~' operator).  As the `**' operator cannot
  be grouped (inside parentheses it is treated as `*'), this is
  one way to exclude some subdirectories from matching a `**'.
  The form (^foo/)# also works.

pws


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

* Re: difference between ~ & ^ negation
  2014-01-02 21:01   ` Peter Stephenson
@ 2014-01-02 21:36     ` Bart Schaefer
  2014-01-02 22:14       ` Peter Stephenson
  2014-01-03  1:55       ` Mikael Magnusson
  0 siblings, 2 replies; 15+ messages in thread
From: Bart Schaefer @ 2014-01-02 21:36 UTC (permalink / raw)
  To: zsh-users

On Jan 2,  9:01pm, Peter Stephenson wrote:
} Subject: Re: difference between ~ & ^ negation
}
} On Wed, 01 Jan 2014 13:44:59 -0800
} Bart Schaefer <schaefer@brasslantern.com> wrote:
} > Important note: ^ is special only in cases where / is special (globs).
} 
} That's not true...
} 
} setopt extendedglob
} [[ foo = ^foo ]] || print foo actually is foo
} [[ bar = ^foo ]] && print but bar is not foo
} 
} "^" is still special here; the difference is that if a "/" appeared
} after it *that* wouldn't be special in this context

Hmm.  So what does that mean about a "^" appearing after a "^" ?  That
is, since / is not special, the expression ^foo/^bar means something
completely different in pattern context and file generation context?

That second caret is the usage I was referring to when I said "only in
cases where / is special".  (Whether or not there is a leading caret.)


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

* Re: difference between ~ & ^ negation
  2014-01-02 21:36     ` Bart Schaefer
@ 2014-01-02 22:14       ` Peter Stephenson
  2014-01-03  1:55       ` Mikael Magnusson
  1 sibling, 0 replies; 15+ messages in thread
From: Peter Stephenson @ 2014-01-02 22:14 UTC (permalink / raw)
  To: zsh-users

On Thu, 02 Jan 2014 13:36:36 -0800
Bart Schaefer <schaefer@brasslantern.com> wrote:
> Hmm.  So what does that mean about a "^" appearing after a "^" ?  That
> is, since / is not special, the expression ^foo/^bar means something
> completely different in pattern context and file generation context?

In pattern context that's the same as ^(foo/^bar).  foo/^bar matches
foo/ followed by anything that's not bar, so this highly useful
expression matches anything except a string consisting of foo/ followed
by something other than bar.

pws


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

* Re: difference between ~ & ^ negation
  2014-01-02 21:36     ` Bart Schaefer
  2014-01-02 22:14       ` Peter Stephenson
@ 2014-01-03  1:55       ` Mikael Magnusson
  2014-01-03  7:37         ` Bart Schaefer
  1 sibling, 1 reply; 15+ messages in thread
From: Mikael Magnusson @ 2014-01-03  1:55 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Zsh Users

On 2 January 2014 22:36, Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Jan 2,  9:01pm, Peter Stephenson wrote:
> } Subject: Re: difference between ~ & ^ negation
> }
> } On Wed, 01 Jan 2014 13:44:59 -0800
> } Bart Schaefer <schaefer@brasslantern.com> wrote:
> } > Important note: ^ is special only in cases where / is special (globs).
> }
> } That's not true...
> }
> } setopt extendedglob
> } [[ foo = ^foo ]] || print foo actually is foo
> } [[ bar = ^foo ]] && print but bar is not foo
> }
> } "^" is still special here; the difference is that if a "/" appeared
> } after it *that* wouldn't be special in this context
>
> Hmm.  So what does that mean about a "^" appearing after a "^" ?  That
> is, since / is not special, the expression ^foo/^bar means something
> completely different in pattern context and file generation context?
>
> That second caret is the usage I was referring to when I said "only in
> cases where / is special".  (Whether or not there is a leading caret.)
>

I think of ^foo as a * that won't match "foo", so you can have
foo/bar^baz and it would match bar* but not barbaz, and if you think
of it like that it's not really that confusing. ^foo/^bar is then just
*/* that won't match */bar or foo/*.

-- 
Mikael Magnusson


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

* Re: difference between ~ & ^ negation
  2014-01-03  1:55       ` Mikael Magnusson
@ 2014-01-03  7:37         ` Bart Schaefer
  2014-01-03 19:48           ` Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Bart Schaefer @ 2014-01-03  7:37 UTC (permalink / raw)
  To: Zsh Users

On Jan 3,  2:55am, Mikael Magnusson wrote:
}
} I think of ^foo as a * that won't match "foo", so you can have
} foo/bar^baz and it would match bar* but not barbaz, and if you think
} of it like that it's not really that confusing. ^foo/^bar is then just
} */* that won't match */bar or foo/*.

Unfortunately that's only helpful for understanding globbing, because in
pattern matching, ^foo/^bar is like * that won't match any foo/* except
specifically foo/bar.  As Peter said, it's implicitly ^(foo/^(bar)) in a
pattern; whereas it's (^(foo))/(^(bar)) in a glob.

There's no other "wildcard" with that weird difference in precedence in
the two cases.  The others differ only on whether "/" is an ordinary
character.  This is what fooled me into thinking it didn't work at all
in a pattern match; I assumed ^foo/^bar was two consecutive expressions,
(^foo/)(^bar), so I constructed the wrong test strings.


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

* Re: difference between ~ & ^ negation
  2014-01-03  7:37         ` Bart Schaefer
@ 2014-01-03 19:48           ` Peter Stephenson
  2014-01-03 20:10             ` Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 2014-01-03 19:48 UTC (permalink / raw)
  To: Zsh Users

Here's an FAQ entry on ^ and ~ since they are obvious confusing.

Corrections or improvements are of course gladly received, but with
explicit suggestions, even partial ones, please, not generalised
complaints as I then don't know what to do about it.

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index bd8ca97..4bc5df6 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -122,6 +122,7 @@ Chapter 3:  How to get various things to work
 3.24. What's wrong with cut and paste on my xterm?
 3.25. How do I get coloured prompts on my colour xterm?
 3.26. Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?
+3.27. What are these `^' and `~' pattern characters, anyway?
 
 Chapter 4:  The mysteries of completion
 4.1. What is completion?
@@ -545,14 +546,8 @@ tt(EXTENDED_GLOB).
       option tt(KSH_GLOB) is in effect; for previous versions you
       must use the table above.
 
-      [1] Note that mytt(~) is the only globbing operator to have a lower
-        precedence than mytt(/).  For example, mytt(**/foo~*bar*) matches any
-        file in a subdirectory called mytt(foo), except where mytt(bar)
-        occurred somewhere in the path (e.g. mytt(users/barstaff/foo) will
-        be excluded by the mytt(~) operator).  As the mytt(**) operator cannot
-        be grouped (inside parentheses it is treated as mytt(*)), this is
-        one way to exclude some subdirectories from matching a mytt(**).
-	The form (^foo/)# also works.
+      [1] See question link(3.27)(327) for more on the mysteries of
+        mytt(~) and mytt(^).
     it()  Unquoted assignments do file expansion after mytt(:)s (intended for
         PATHs). 
     it()* mytt(typeset) and mytt(integer) have special behaviour for
@@ -1452,6 +1447,8 @@ sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something f
   are metacharacters.  tt(^a) matches any file except one called tt(a), so the
   line is interpreted as bindkey followed by a list of files.  Quote the
   tt(^) with a backslash or put quotation marks around tt(^a).
+  See link(3.27)(327) if you want to know more about the pattern
+  character mytt(^).
 
 
 sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?)
@@ -1668,6 +1665,7 @@ sect(How do I prevent the prompt overwriting output when there is no newline?)
   One final alternative is to put a newline in your prompt -- see question
   link(3.13)(313) for that.
 
+
 sect(What's wrong with cut and paste on my xterm?)
 
   On the majority of modern UNIX systems, cutting text from one window and
@@ -1700,6 +1698,7 @@ sect(What's wrong with cut and paste on my xterm?)
      fixes referred to above in order to be reliable).
   )
 
+
 sect(How do I get coloured prompts on my colour xterm?)
 
   (Or `color xterm', if you're reading this in black and white.)
@@ -1743,6 +1742,7 @@ sect(How do I get coloured prompts on my colour xterm?)
   `mytt(<ESC>[0m)' puts printing back to normal so that the rest of the line
   is unchanged.
 
+
 sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?)
 
   This is a slightly unexpected effect of the option tt(MULTIOS), which is
@@ -1780,6 +1780,122 @@ sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?)
   to unset the option mytt(MULTIOS).
 
 
+sect(What are these `^' and `~' pattern characters, anyway?)
+label(327)
+
+  The characters mytt(^) and mytt(~) are active when the option
+  tt(EXTENDED_GLOB) is set.  Both are used to exclude patterns, i.e.  to
+  say `match something other than ...'.  There are some confusing
+  differences, however.  Here are the descriptions for mytt(^) and mytt(~).
+
+  mytt(^) means `anything except the pattern that follows'.  You can
+  think of the combination tt(^)em(pat) as being like a tt(*) except
+  that it doesn't match em(pat).  So, for example, mytt(myfile^.txt)
+  matches anything that begins with tt(myfile) except tt(myfile.txt).
+  Because it works with patterns, not just strings, mytt(myfile^*.c)
+  matches anything that begins with tt(myfile) unless it ends with
+  tt(.c), whatever comes in the middle --- so it matches tt(myfile1.h)
+  but not tt(myfile1.c).
+
+  Also like mytt(*), mytt(^) doesn't match across directories if you're
+  matching files when `globbing', i.e. when you use an unquoted pattern
+  in an ordinary command line to generate file names.  So
+  mytt(^dir1/^file1) matches any subdirectory of the current directory
+  except one called tt(dir1), and within any directory it matches it
+  picks any file except one called tt(file1).  So the overall pattern
+  matches tt(dir2/file2) but not tt(dir1/file1) nor tt(dir1/file2) nor
+  tt(dir2/file1).  (The rule that all the different bits of the pattern
+  must match is exactly the same as for any other pattern character,
+  it's just a little confusing that what em(does) match in each bit is
+  found by telling the shell em(not) to match something or other.)
+
+  As with any other pattern, a mytt(^) expression doesn't treat the
+  character `tt(/)' specially if it's not matching files, for example
+  when pattern matching in a command like mytt([[ $string = ^pat1/pat2 ]]).
+  Here the whole string tt(pat1/pat2) is treated as the argument that
+  follows the mytt(^).  So anything matches but that one string
+  tt(pat1/pat1).
+
+  It's not obvious what something like mytt([[ $string = ^pat1^pat2 ]])
+  means.  You won't often have cause to use it, but the rule is that
+  each mytt(^) takes em(everything) that follows as an argument (unless
+  it's already inside parentheses --- I'll explain this below).  To see
+  this more clearly, put those arguments in parentheses: the pattern is
+  equivalent to mytt(^(pat1^(pat2))). where now you can see exactly what
+  each mytt(^) takes as its argument.  I'll leave it as an exercise for
+  you to work out what this does and doesn't match.
+  
+  mytt(~) is always used between two patterns --- never right at the
+  beginning or right at the end.  Note that the other special meaning of
+  mytt(~), at the start of a filename to refer to your home directory or
+  the another named directory, doesn't require the option
+  tt(EXTENDED_GLOB) to be set.  (At the end of an argument mytt(~) is
+  never special at all.  This is useful if you have Emacs backup files.)
+  It means `match what's in front of the tilde, but only if it doesn't
+  match what's after the tilde'.  So mytt(*.c~f*) matches any file
+  ending in tt(.c) except one that begins with tt(f).  You'll see that,
+  unlike mytt(^), the parts before and after the mytt(~) both refer
+  separately to the entire test string.
+
+  For matching files by globbing, mytt(~) is the only globbing
+  operator to have a lower precedence than mytt(/).  In other words,
+  when you have mytt(/a/path/to/match~/a/path/not/to/match) the mytt(~)
+  considers what's before and what's after as complete paths to file names.
+  You can put any other pattern characters in the expressions before and
+  after the mytt(~), but note that the pattern after the tt(~) is really
+  just a single pattern to match against every file found.  That means,
+  for example, that a tt(*) after the tt(~) em(will) match a tt(/).
+  If that's confusing, you can think of how mytt(~) works like this:
+  take the pattern on the left, use it as normal to make a list of
+  files, then for each file found see if it matches the pattern on the
+  right and if it does take that file out of the list.
+
+  One rule that is common to both mytt(^) and mytt(~) is that they can
+  be put inside parentheses and the arguments to them don't extend past
+  the parentheses.  So mytt((^README).txt) matches any file ending in
+  tt(.txt) unless it starts with tt(README), the same as
+  mytt(README*~*.txt).  Likewise, mytt(abc(<->~<10-100>).txt) matches a
+  file consisting of tt(abc), then some digits, then tt(.txt), unless
+  the digits happen to match a number from 10 to 100 inclusive (remember
+  the handy mytt(<->) pattern for matching integers with optional limits
+  to the range).  So this pattern matches tt(abc1.txt) or tt(abc200.txt)
+  but not tt(abc20.txt) nor tt(abc100.txt) nor even tt(abc0030.txt).
+  However, if you're matching files by globbing note you can't put
+  mytt(/)s inside the parentheses since the groups can't stretch across
+  multiple directories.  (You can do that, of course, whenever the
+  character mytt(/) isn't special.)
+
+  You may like to know that from zsh 5.0.2 you can disable any pattern
+  character separately.  So if you find mytt(^) gets in your way and
+  you're happy using mytt(~), put mytt(disable -p "^") in tt(~/.zshrc).
+  You still need to turn on tt(EXTENDED_GLOB); the tt(disable) command
+  only deactivates things that would otherwise be active, you can't
+  specially enable something not allowed by the syntax options in effect.
+
+  Here are some examples with files to illustrate the points.  We'll
+  assume the option tt(EXTENDED_GLOB) is set.
+
+  enumerate(
+  myeit() mytt(**/foo~*bar*) matches any file in a subdirectory called
+     mytt(foo), except where mytt(bar) occurred somewhere in the path
+     (e.g. mytt(users/barstaff/foo) will be excluded by the mytt(~)
+     operator).  As the mytt(**) operator cannot be grouped (inside
+     parentheses it is treated as mytt(*)), this is one way to exclude some
+     subdirectories from matching a mytt(**).  Note that this can be quite
+     inefficent because the shell performs a complete search for
+     mytt(**/foo) before it uses the pattern after the mytt(~) to exclude
+     files from the match.  The file is excluded if mytt(bar) occurs
+     em(anywhere), in any directory segment or the final file name.
+  myeit() The form mytt((^foo/)#) can be used to match any hierarchy of
+     files where none of the path components is tt(foo).  For
+     example, mytt((^CVS/)#) selects all subdirectories to any depth
+     except where one component is named mytt(CVS).  (The form
+     mytt((pat/)#) is very useful in other cases; for example,
+     mytt((../)#.cvsignore) finds the file tt(.cvsignore) if it exists
+     in the current directory or any parent.)
+  )
+
+
 chapter(The mysteries of completion)
 
 
 
 
-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: difference between ~ & ^ negation
  2014-01-03 19:48           ` Peter Stephenson
@ 2014-01-03 20:10             ` Peter Stephenson
  2014-01-03 21:43               ` Bart Schaefer
  0 siblings, 1 reply; 15+ messages in thread
From: Peter Stephenson @ 2014-01-03 20:10 UTC (permalink / raw)
  To: Zsh Users

On Fri, 3 Jan 2014 19:48:02 +0000
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> Here's an FAQ entry on ^ and ~ since they are obvious confusing.

Corrections I spotted myself before anyone else picks nits.

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index bd8ca97..bb17ceb 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -122,6 +122,7 @@ Chapter 3:  How to get various things to work
 3.24. What's wrong with cut and paste on my xterm?
 3.25. How do I get coloured prompts on my colour xterm?
 3.26. Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?
+3.27. What are these `^' and `~' pattern characters, anyway?
 
 Chapter 4:  The mysteries of completion
 4.1. What is completion?
@@ -545,14 +546,8 @@ tt(EXTENDED_GLOB).
       option tt(KSH_GLOB) is in effect; for previous versions you
       must use the table above.
 
-      [1] Note that mytt(~) is the only globbing operator to have a lower
-        precedence than mytt(/).  For example, mytt(**/foo~*bar*) matches any
-        file in a subdirectory called mytt(foo), except where mytt(bar)
-        occurred somewhere in the path (e.g. mytt(users/barstaff/foo) will
-        be excluded by the mytt(~) operator).  As the mytt(**) operator cannot
-        be grouped (inside parentheses it is treated as mytt(*)), this is
-        one way to exclude some subdirectories from matching a mytt(**).
-	The form (^foo/)# also works.
+      [1] See question link(3.27)(327) for more on the mysteries of
+        mytt(~) and mytt(^).
     it()  Unquoted assignments do file expansion after mytt(:)s (intended for
         PATHs). 
     it()* mytt(typeset) and mytt(integer) have special behaviour for
@@ -1452,6 +1447,8 @@ sect(Why does mytt(bindkey ^a command-name) or mytt(stty intr ^-) do something f
   are metacharacters.  tt(^a) matches any file except one called tt(a), so the
   line is interpreted as bindkey followed by a list of files.  Quote the
   tt(^) with a backslash or put quotation marks around tt(^a).
+  See link(3.27)(327) if you want to know more about the pattern
+  character mytt(^).
 
 
 sect(Why can't I bind tt(\C-s) and tt(\C-q) any more?)
@@ -1668,6 +1665,7 @@ sect(How do I prevent the prompt overwriting output when there is no newline?)
   One final alternative is to put a newline in your prompt -- see question
   link(3.13)(313) for that.
 
+
 sect(What's wrong with cut and paste on my xterm?)
 
   On the majority of modern UNIX systems, cutting text from one window and
@@ -1700,6 +1698,7 @@ sect(What's wrong with cut and paste on my xterm?)
      fixes referred to above in order to be reliable).
   )
 
+
 sect(How do I get coloured prompts on my colour xterm?)
 
   (Or `color xterm', if you're reading this in black and white.)
@@ -1743,6 +1742,7 @@ sect(How do I get coloured prompts on my colour xterm?)
   `mytt(<ESC>[0m)' puts printing back to normal so that the rest of the line
   is unchanged.
 
+
 sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?)
 
   This is a slightly unexpected effect of the option tt(MULTIOS), which is
@@ -1780,6 +1780,128 @@ sect(Why is my output duplicated with `tt(foo 2>&1 >foo.out | bar)'?)
   to unset the option mytt(MULTIOS).
 
 
+sect(What are these `^' and `~' pattern characters, anyway?)
+label(327)
+
+  The characters mytt(^) and mytt(~) are active when the option
+  tt(EXTENDED_GLOB) is set.  Both are used to exclude patterns, i.e.  to
+  say `match something other than ...'.  There are some confusing
+  differences, however.  Here are the descriptions for mytt(^) and mytt(~).
+
+  mytt(^) means `anything except the pattern that follows'.  You can
+  think of the combination tt(^)em(pat) as being like a tt(*) except
+  that it doesn't match em(pat).  So, for example, mytt(myfile^.txt)
+  matches anything that begins with tt(myfile) except tt(myfile.txt).
+  Because it works with patterns, not just strings, mytt(myfile^*.c)
+  matches anything that begins with tt(myfile) unless it ends with
+  tt(.c), whatever comes in the middle --- so it matches tt(myfile1.h)
+  but not tt(myfile1.c).
+
+  Also like mytt(*), mytt(^) doesn't match across directories if you're
+  matching files when `globbing', i.e. when you use an unquoted pattern
+  in an ordinary command line to generate file names.  So
+  mytt(^dir1/^file1) matches any subdirectory of the current directory
+  except one called tt(dir1), and within any directory it matches it
+  picks any file except one called tt(file1).  So the overall pattern
+  matches tt(dir2/file2) but not tt(dir1/file1) nor tt(dir1/file2) nor
+  tt(dir2/file1).  (The rule that all the different bits of the pattern
+  must match is exactly the same as for any other pattern character,
+  it's just a little confusing that what em(does) match in each bit is
+  found by telling the shell em(not) to match something or other.)
+
+  As with any other pattern, a mytt(^) expression doesn't treat the
+  character `tt(/)' specially if it's not matching files, for example
+  when pattern matching in a command like mytt([[ $string = ^pat1/pat2 ]]).
+  Here the whole string tt(pat1/pat2) is treated as the argument that
+  follows the mytt(^).  So anything matches but that one string
+  tt(pat1/pat1).
+
+  It's not obvious what something like mytt([[ $string = ^pat1^pat2 ]])
+  means.  You won't often have cause to use it, but the rule is that
+  each mytt(^) takes em(everything) that follows as an argument (unless
+  it's already inside parentheses --- I'll explain this below).  To see
+  this more clearly, put those arguments in parentheses: the pattern is
+  equivalent to mytt(^(pat1^(pat2))). where now you can see exactly what
+  each mytt(^) takes as its argument.  I'll leave it as an exercise for
+  you to work out what this does and doesn't match.
+  
+  mytt(~) is always used between two patterns --- never right at the
+  beginning or right at the end.  Note that the other special meaning of
+  mytt(~), at the start of a filename to refer to your home directory or
+  the another named directory, doesn't require the option
+  tt(EXTENDED_GLOB) to be set.  (At the end of an argument mytt(~) is
+  never special at all.  This is useful if you have Emacs backup files.)
+  It means `match what's in front of the tilde, but only if it doesn't
+  match what's after the tilde'.  So mytt(*.c~f*) matches any file
+  ending in tt(.c) except one that begins with tt(f).  You'll see that,
+  unlike mytt(^), the parts before and after the mytt(~) both refer
+  separately to the entire test string.
+
+  For matching files by globbing, mytt(~) is the only globbing
+  operator to have a lower precedence than mytt(/).  In other words,
+  when you have mytt(/a/path/to/match~/a/path/not/to/match) the mytt(~)
+  considers what's before and what's after as complete paths to file names.
+  You can put any other pattern characters in the expressions before and
+  after the mytt(~), but note that the pattern after the tt(~) is really
+  just a single pattern to match against every file found.  That means,
+  for example, that a tt(*) after the tt(~) em(will) match a tt(/).
+  If that's confusing, you can think of how mytt(~) works like this:
+  take the pattern on the left, use it as normal to make a list of
+  files, then for each file found see if it matches the pattern on the
+  right and if it does take that file out of the list.
+
+  One rule that is common to both mytt(^) and mytt(~) is that they can
+  be put inside parentheses and the arguments to them don't extend past
+  the parentheses.  So mytt((^README).txt) matches any file ending in
+  tt(.txt) unless the string before that was tt(README), the same as
+  mytt(*.txt~README.txt) or mytt((*~README).txt).  In fact, you can
+  always turn mytt(^something) into mytt((*~something)), where
+  mytt(something) mustn't contain tt(/) if the pattern is being used for
+  globbing.
+
+  Likewise, mytt(abc(<->~<10-100>).txt) matches a file consisting of
+  tt(abc), then some digits, then tt(.txt), unless the digits happen to
+  match a number from 10 to 100 inclusive (remember the handy mytt(<->)
+  pattern for matching integers with optional limits to the range).  So
+  this pattern matches tt(abc1.txt) or tt(abc200.txt) but not
+  tt(abc20.txt) nor tt(abc100.txt) nor even tt(abc0030.txt).  However,
+  if you're matching files by globbing note you can't put mytt(/)s
+  inside the parentheses since the groups can't stretch across multiple
+  directories.  (You can do that, of course, whenever the character
+  mytt(/) isn't special.)
+
+  You may like to know that from zsh 5.0.3 you can disable any pattern
+  character separately.  So if you find mytt(^) gets in your way and
+  you're happy using mytt(~), put mytt(disable -p "^") in tt(~/.zshrc).
+  You still need to turn on tt(EXTENDED_GLOB); the tt(disable) command
+  only deactivates things that would otherwise be active, you can't
+  specially enable something not allowed by the syntax options in effect.
+
+  Here are some examples with files to illustrate the points.  We'll
+  assume the option tt(EXTENDED_GLOB) is set and none of the pattern
+  characters is disabled.
+
+  enumerate(
+  myeit() mytt(**/foo~*bar*) matches any file called mytt(foo) in any
+     subdirectory, except where mytt(bar) occurred somewhere in the path.
+     For example, mytt(users/barstaff/foo) will be excluded by the mytt(~)
+     operator.  As the mytt(**) operator cannot be grouped (inside
+     parentheses it is treated as mytt(*)), this is one way to exclude some
+     subdirectories from matching a mytt(**).  Note that this can be quite
+     inefficent because the shell performs a complete search for
+     mytt(**/foo) before it uses the pattern after the mytt(~) to exclude
+     files from the match.  The file is excluded if mytt(bar) occurs
+     em(anywhere), in any directory segment or the final file name.
+  myeit() The form mytt((^foo/)#) can be used to match any hierarchy of
+     directories where none of the path components is tt(foo).  For
+     example, mytt((^CVS/)#) selects all subdirectories to any depth
+     except where one component is named mytt(CVS).  (The form
+     mytt((pat/)#) is very useful in other cases; for example,
+     mytt((../)#.cvsignore) finds the file tt(.cvsignore) if it exists
+     in the current directory or any parent.)
+  )
+
+
 chapter(The mysteries of completion)
 
 
-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* how to shut off auto spell
       [not found] ` <8lp61n01B02mHnv01lp8uc>
@ 2014-01-03 20:56   ` steve
  2014-01-03 21:52     ` Bart Schaefer
       [not found]     ` <9ZwH1n01Z02mHnv01ZwLWZ>
  0 siblings, 2 replies; 15+ messages in thread
From: steve @ 2014-01-03 20:56 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

I have this in my .zshrc :

	alias sails="nocorrect sails"

Every time I try to do a 

	sails lift 

to start sails.js I get a spell correction.

I think I found that somewhere from google, but apparently it's not working.

Thank you,
Steve


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

* Re: difference between ~ & ^ negation
  2014-01-03 20:10             ` Peter Stephenson
@ 2014-01-03 21:43               ` Bart Schaefer
  2014-01-04 21:11                 ` zzapper
  0 siblings, 1 reply; 15+ messages in thread
From: Bart Schaefer @ 2014-01-03 21:43 UTC (permalink / raw)
  To: Zsh Users

On Jan 3,  8:10pm, Peter Stephenson wrote:
} 
} Corrections I spotted myself before anyone else picks nits.

Sadly, here come some nits anyway.

} +  For matching files by globbing, mytt(~) is the only globbing
} +  operator to have a lower precedence than mytt(/).  In other words,
} +  when you have mytt(/a/path/to/match~/a/path/not/to/match) the mytt(~)
} +  considers what's before and what's after as complete paths to file names.

In my first response on this thread, I struggled mightily with how to
explain exactly how the before/after patterns are applied.  The phrase
"complete paths to file names" might be considered to mean that the
paths must start from the root (which your example further suggests),
but in fact they're not "complete" paths.  For purposes of the pattern
before the tilde, it matches ordinary path references which unless begun
with a slash are relative to $PWD.  For purposes of the pattern after
the tilde, it matches strings, which merely happen to be [parts of] the
names of things derived from the paths matched by the before part.

} +  You can put any other pattern characters in the expressions before and
} +  after the mytt(~), but note that the pattern after the tt(~) is really
} +  just a single pattern to match against every file found.

This is what I mean ... it doesn't match against the *file* (so, e.g.,
qualifiers such as (@) or (/) don't matter) -- it matches against the
*path name* of the file.

} +  If that's confusing, you can think of how mytt(~) works like this:
} +  take the pattern on the left, use it as normal to make a list of
} +  files, then for each file found see if it matches the pattern on the
} +  right and if it does take that file out of the list.

Except thinking of it that way is misleading, because the other hard-
to-grasp bit of this is that the after-pattern is matched against the
name of each file AS IT IS FOUND by matching the before-pattern, *not*
as a filter over the list of names after they are all found.  That
means that it's applied *before* any glob qualifiers including (e:...:)
or (+...).

} +  if you're matching files by globbing note you can't put mytt(/)s
} +  inside the parentheses since the groups can't stretch across multiple
} +  directories.  (You can do that, of course, whenever the character
} +  mytt(/) isn't special.)

Which means you can only exclude multi-segment paths by using ~pat/tern
at the very end of a glob.  Another gotcha with the parenthesizing bit
is that ^ is also a qualifier, so (^foo) at the end of glob is parsed
as a qualifier unless you add more parens or have NO_BARE_GLOB_QUAL.


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

* Re: how to shut off auto spell
  2014-01-03 20:56   ` how to shut off auto spell steve
@ 2014-01-03 21:52     ` Bart Schaefer
       [not found]     ` <9ZwH1n01Z02mHnv01ZwLWZ>
  1 sibling, 0 replies; 15+ messages in thread
From: Bart Schaefer @ 2014-01-03 21:52 UTC (permalink / raw)
  To: zsh-users

On Jan 3,  1:56pm, steve wrote:
} Subject: how to shut off auto spell
}
} I have this in my .zshrc :
} 
} 	alias sails="nocorrect sails"
} 
} Every time I try to do a 
} 
} 	sails lift 
} 
} to start sails.js I get a spell correction.

What gets corrected?  "sails" or "lift"?

By what mechanism would "sails" turn into "sails.js"?

If you run

    alias sails

what do you see?


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

* Re: how to shut off auto spell
       [not found]     ` <9ZwH1n01Z02mHnv01ZwLWZ>
@ 2014-01-03 22:07       ` steve
  0 siblings, 0 replies; 15+ messages in thread
From: steve @ 2014-01-03 22:07 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users

My apology, I wasn't thinking, I was making this harder than it needed to be.
I set :

	alias sl='sails lift'

in .zshrc and all is well.

Steve



On Jan 3, 2014, at 2:52 PM, Bart Schaefer <schaefer@brasslantern.com> wrote:

> On Jan 3,  1:56pm, steve wrote:
> } Subject: how to shut off auto spell
> }
> } I have this in my .zshrc :
> } 
> } 	alias sails="nocorrect sails"
> } 
> } Every time I try to do a 
> } 
> } 	sails lift 
> } 
> } to start sails.js I get a spell correction.
> 
> What gets corrected?  "sails" or "lift"?
> 
> By what mechanism would "sails" turn into "sails.js"?
> 
> If you run
> 
>    alias sails
> 
> what do you see?


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

* Re: difference between ~ & ^ negation
  2014-01-03 21:43               ` Bart Schaefer
@ 2014-01-04 21:11                 ` zzapper
  2014-01-05 10:01                   ` Eike von Seggern
  0 siblings, 1 reply; 15+ messages in thread
From: zzapper @ 2014-01-04 21:11 UTC (permalink / raw)
  To: zsh-users

Bart Schaefer <schaefer@brasslantern.com> wrote in
news:140103134326.ZM11500@torch.brasslantern.com: 

> On Jan 3,  8:10pm, Peter Stephenson wrote:
> } 
> } Corrections I spotted myself before anyone else picks nits.
> 
> Sadly, here come some nits anyway.
> 
> } +  For matching files by globbing, mytt(~) is the only globbing
> } +  operator to have a lower precedence than mytt(/).  In other
> words, } +  when you have mytt(/a/path/to/match~/a/path/not/to/match)
> the mytt(~) } +  considers what's before and what's after as complete
> paths to file names. 
> 
> In my first response on this thread, I struggled mightily with how to
> explain exactly how the before/after patterns are applied.  The phrase
> "complete paths to file names" might be considered to mean that the
> paths must start from the root (which your example further suggests),
> but in fact they're not "complete" paths.  For purposes of the pattern
> before the tilde, it matches ordinary path references which unless
> begun with a slash are relative to $PWD.  For purposes of the pattern
> after the tilde, it matches strings, which merely happen to be [parts
> of] the names of things derived from the paths matched by the before
> part. 

Hi will there be a summary of this for us mere mortals :)

Will the FAQs be changed and if so can you point us at the relevant 
sections

zzapper



---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com



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

* Re: difference between ~ & ^ negation
  2014-01-04 21:11                 ` zzapper
@ 2014-01-05 10:01                   ` Eike von Seggern
  0 siblings, 0 replies; 15+ messages in thread
From: Eike von Seggern @ 2014-01-05 10:01 UTC (permalink / raw)
  To: zsh-users

On Sat, Jan 04, 2014 at 21:11 +0000, zzapper wrote:
> Will the FAQs be changed and if so can you point us at the relevant
> sections

According to Peter's diff it will be Section 3.27.

Regards,
Eike


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

end of thread, other threads:[~2014-01-05 10:09 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-01 15:28 difference between ~ & ^ negation zzapper
2014-01-01 21:44 ` Bart Schaefer
2014-01-02 21:01   ` Peter Stephenson
2014-01-02 21:36     ` Bart Schaefer
2014-01-02 22:14       ` Peter Stephenson
2014-01-03  1:55       ` Mikael Magnusson
2014-01-03  7:37         ` Bart Schaefer
2014-01-03 19:48           ` Peter Stephenson
2014-01-03 20:10             ` Peter Stephenson
2014-01-03 21:43               ` Bart Schaefer
2014-01-04 21:11                 ` zzapper
2014-01-05 10:01                   ` Eike von Seggern
     [not found] ` <8lp61n01B02mHnv01lp8uc>
2014-01-03 20:56   ` how to shut off auto spell steve
2014-01-03 21:52     ` Bart Schaefer
     [not found]     ` <9ZwH1n01Z02mHnv01ZwLWZ>
2014-01-03 22:07       ` steve

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