* 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
* 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: 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
[parent not found: <8lp61n01B02mHnv01lp8uc>]
* 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: 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
[parent not found: <9ZwH1n01Z02mHnv01ZwLWZ>]
* 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
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).