zsh-users
 help / color / Atom feed
* Glob and grep
@ 2019-12-16 22:44 Nick Cross
  2019-12-16 23:10 ` Mikael Magnusson
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Nick Cross @ 2019-12-16 22:44 UTC (permalink / raw)
  To: Zsh Users


Hi,

While I've been able to find varying amounts of information on the net I 
haven't found quite enough to get the following working.

I would like to condense the following into a single grep / glob 
expression where I search recursively through a directory tree, ignoring 
any sub-trees starting with 'test' or 'target'.

grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"

While I found information about ^(xxx) it wasn't clear how to have 
multiple expressions to ignore.

Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only 
search for files as well ?


Thanks

Nick

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

* Re: Glob and grep
  2019-12-16 22:44 Glob and grep Nick Cross
@ 2019-12-16 23:10 ` Mikael Magnusson
  2019-12-16 23:24   ` Dominik Vogt
  2019-12-17  7:31   ` Nick Cross
  2019-12-16 23:18 ` dana
  2019-12-17 10:00 ` zzapper
  2 siblings, 2 replies; 10+ messages in thread
From: Mikael Magnusson @ 2019-12-16 23:10 UTC (permalink / raw)
  To: Nick Cross; +Cc: Zsh Users

On 12/16/19, Nick Cross <zsh@goots.org> wrote:
>
> Hi,
>
> While I've been able to find varying amounts of information on the net I
> haven't found quite enough to get the following working.
>
> I would like to condense the following into a single grep / glob
> expression where I search recursively through a directory tree, ignoring
> any sub-trees starting with 'test' or 'target'.
>
> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"
>
> While I found information about ^(xxx) it wasn't clear how to have
> multiple expressions to ignore.
>
> Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only
> search for files as well ?

I think what you want is
grep <pattern> (^(test|target)/)#*.groovy(.)

-- 
Mikael Magnusson

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

* Re: Glob and grep
  2019-12-16 22:44 Glob and grep Nick Cross
  2019-12-16 23:10 ` Mikael Magnusson
@ 2019-12-16 23:18 ` dana
  2019-12-17  7:30   ` Nick Cross
  2019-12-17 10:00 ` zzapper
  2 siblings, 1 reply; 10+ messages in thread
From: dana @ 2019-12-16 23:18 UTC (permalink / raw)
  To: Nick Cross; +Cc: Zsh Users

On 16 Dec 2019, at 16:44, Nick Cross <zsh@goots.org> wrote:
> While I found information about ^(xxx) it wasn't clear how to have multiple
> expressions to ignore.

In addition to Mikael's suggestion you can also use the x~y syntax, which i
personally find less confusing, and is effectively `m/x/ && !m/y/` in Perl:

  **/*.groovy~*/(test|target)/*
  # or you can chain multiple y patterns
  **/*.groovy~*/test/*~*/target/*

(Note that, like zshexpn(1) says, / and . are not special in the y pattern)

On 16 Dec 2019, at 16:44, Nick Cross <zsh@goots.org> wrote:
> Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only
> search for files as well ?

Use (-.) if you also want to match symlinks to files (which is common)

dana


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

* Re: Glob and grep
  2019-12-16 23:10 ` Mikael Magnusson
@ 2019-12-16 23:24   ` Dominik Vogt
  2019-12-17  1:20     ` Daniel Shahaf
  2019-12-17  7:31   ` Nick Cross
  1 sibling, 1 reply; 10+ messages in thread
From: Dominik Vogt @ 2019-12-16 23:24 UTC (permalink / raw)
  To: zsh-users

On 12/16/19, Nick Cross <zsh@goots.org> wrote:
> While I've been able to find varying amounts of information on the net I
> haven't found quite enough to get the following working.
>
> I would like to condense the following into a single grep / glob
> expression where I search recursively through a directory tree, ignoring
> any sub-trees starting with 'test' or 'target'.
>
> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"

Or a zsh-less solution:

 $ grep -R --include="*.groovy" --exclude-dir=test --exclude-dir=target a .

Ciao

Dominik ^_^  ^_^

--

Dominik Vogt

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

* Re: Glob and grep
  2019-12-16 23:24   ` Dominik Vogt
@ 2019-12-17  1:20     ` Daniel Shahaf
  2019-12-17  7:31       ` Nick Cross
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Shahaf @ 2019-12-17  1:20 UTC (permalink / raw)
  To: zsh-users

Dominik Vogt wrote on Tue, Dec 17, 2019 at 00:24:27 +0100:
> On 12/16/19, Nick Cross <zsh@goots.org> wrote:
> > While I've been able to find varying amounts of information on the net I
> > haven't found quite enough to get the following working.
> >
> > I would like to condense the following into a single grep / glob
> > expression where I search recursively through a directory tree, ignoring
> > any sub-trees starting with 'test' or 'target'.
> >
> > grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"
> 
> Or a zsh-less solution:
> 
>  $ grep -R --include="*.groovy" --exclude-dir=test --exclude-dir=target a .

If the tree is in version control, there's another way:

rm -rf **/(test|target)(N)
grep needle **/.haystack
<restore the deleted files>

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

* Re: Glob and grep
  2019-12-16 23:18 ` dana
@ 2019-12-17  7:30   ` Nick Cross
  0 siblings, 0 replies; 10+ messages in thread
From: Nick Cross @ 2019-12-17  7:30 UTC (permalink / raw)
  To: dana; +Cc: Zsh Users

On 16/12/2019 23:18, dana wrote:
> On 16 Dec 2019, at 16:44, Nick Cross <zsh@goots.org> wrote:
>> While I found information about ^(xxx) it wasn't clear how to have multiple
>> expressions to ignore.
> 
> In addition to Mikael's suggestion you can also use the x~y syntax, which i
> personally find less confusing, and is effectively `m/x/ && !m/y/` in Perl:
> 
>    **/*.groovy~*/(test|target)/*
>    # or you can chain multiple y patterns
>    **/*.groovy~*/test/*~*/target/*
> 
> (Note that, like zshexpn(1) says, / and . are not special in the y pattern)
> 
> On 16 Dec 2019, at 16:44, Nick Cross <zsh@goots.org> wrote:
>> Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only
>> search for files as well ?
> 
> Use (-.) if you also want to match symlinks to files (which is common)
> 
> dana
> 


Firstly, thanks everyone for the replies. The '~' syntax is interesting; 
so effectively the negated options are put at the end.

Nick

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

* Re: Glob and grep
  2019-12-17  1:20     ` Daniel Shahaf
@ 2019-12-17  7:31       ` Nick Cross
  0 siblings, 0 replies; 10+ messages in thread
From: Nick Cross @ 2019-12-17  7:31 UTC (permalink / raw)
  To: Daniel Shahaf, zsh-users

On 17/12/2019 01:20, Daniel Shahaf wrote:
> Dominik Vogt wrote on Tue, Dec 17, 2019 at 00:24:27 +0100:
>> On 12/16/19, Nick Cross <zsh@goots.org> wrote:
>>> While I've been able to find varying amounts of information on the net I
>>> haven't found quite enough to get the following working.
>>>
>>> I would like to condense the following into a single grep / glob
>>> expression where I search recursively through a directory tree, ignoring
>>> any sub-trees starting with 'test' or 'target'.
>>>
>>> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"
>>
>> Or a zsh-less solution:
>>
>>   $ grep -R --include="*.groovy" --exclude-dir=test --exclude-dir=target a .
> 
> If the tree is in version control, there's another way:
> 
> rm -rf **/(test|target)(N)
> grep needle **/.haystack
> <restore the deleted files>
> 


Woah - the nuke it from orbit option!!


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

* Re: Glob and grep
  2019-12-16 23:10 ` Mikael Magnusson
  2019-12-16 23:24   ` Dominik Vogt
@ 2019-12-17  7:31   ` Nick Cross
  2019-12-17  9:39     ` Mikael Magnusson
  1 sibling, 1 reply; 10+ messages in thread
From: Nick Cross @ 2019-12-17  7:31 UTC (permalink / raw)
  To: Mikael Magnusson, Nick Cross; +Cc: Zsh Users

On 16/12/2019 23:10, Mikael Magnusson wrote:
> On 12/16/19, Nick Cross <zsh@goots.org> wrote:
>>
>> Hi,
>>
>> While I've been able to find varying amounts of information on the net I
>> haven't found quite enough to get the following working.
>>
>> I would like to condense the following into a single grep / glob
>> expression where I search recursively through a directory tree, ignoring
>> any sub-trees starting with 'test' or 'target'.
>>
>> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"
>>
>> While I found information about ^(xxx) it wasn't clear how to have
>> multiple expressions to ignore.
>>
>> Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only
>> search for files as well ?
> 
> I think what you want is
> grep <pattern> (^(test|target)/)#*.groovy(.)
> 

Thats great thanks! Works perfectly.

So to break it down - the ^ negates the or'd block. Can you explain how 
the wrapped (../) and # then works please?

Thanks

Nick

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

* Re: Glob and grep
  2019-12-17  7:31   ` Nick Cross
@ 2019-12-17  9:39     ` Mikael Magnusson
  0 siblings, 0 replies; 10+ messages in thread
From: Mikael Magnusson @ 2019-12-17  9:39 UTC (permalink / raw)
  To: Nick Cross; +Cc: Zsh Users

On 12/17/19, Nick Cross <zsh@goots.org> wrote:
> On 16/12/2019 23:10, Mikael Magnusson wrote:
>> On 12/16/19, Nick Cross <zsh@goots.org> wrote:
>>>
>>> Hi,
>>>
>>> I would like to condense the following into a single grep / glob
>>> expression where I search recursively through a directory tree, ignoring
>>> any sub-trees starting with 'test' or 'target'.
>>>
>>> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"
>>>
>>> Am I right in thinking I can add (.) to e.g. *.groovy to ensure I only
>>> search for files as well ?
>>
>> I think what you want is
>> grep <pattern> (^(test|target)/)#*.groovy(.)
>>
>
> Thats great thanks! Works perfectly.
>
> So to break it down - the ^ negates the or'd block. Can you explain how
> the wrapped (../) and # then works please?

Sure, you already know about the **/ operator, what you probably
didn't know is that it's a shorthand for (*/)# which means */ repeated
0 or more times. We can replace the * by another pattern here, for
example ((abc|xyz)/)# would match abc/abc and abc/xyz/xyz/abc/abc etc.

A good way to think about (^foo) is like a * that will not expand to
exactly foo. If you write *^hello you might think you'll match every
file not ending in hello, but in fact you will match every file; the
first * will simply match the entire string and then ^hello will match
the empty string (or indeed "ello" or some other valid combination).

The above method should be the most efficient way to do this, using
**/*.groovy~*/(test|target)/* will first recurse through the entire
tree, including test/ and target/, generate the whole list of matches,
and then filter it by the pattern(s) given by ~. Depending on how
large the test/target directories are, this can be a significant
difference. It is probably easier to think about how ~ works though.

-- 
Mikael Magnusson

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

* Re: Glob and grep
  2019-12-16 22:44 Glob and grep Nick Cross
  2019-12-16 23:10 ` Mikael Magnusson
  2019-12-16 23:18 ` dana
@ 2019-12-17 10:00 ` zzapper
  2 siblings, 0 replies; 10+ messages in thread
From: zzapper @ 2019-12-17 10:00 UTC (permalink / raw)
  To: zsh-users

Nick Cross <zsh@goots.org> wrote in news:15c62c86-5b55-e248-725f-
4ecbfe73822d@goots.org:

> 
> Hi,
> 
> While I've been able to find varying amounts of information on the net 
I 
> haven't found quite enough to get the following working.
> 
> I would like to condense the following into a single grep / glob 
> expression where I search recursively through a directory tree, 
ignoring 
> any sub-trees starting with 'test' or 'target'.
> 
> grep <pattern> **/*.groovy  | egrep -v "(/test/|/target/)"

# zargs cope with large hierarchy

autoload zargs
zargs **/*.(js|php|css|inc)~(|libs|test|temp|node*|dump)/*~*/junk/* --
grep -i 2>/dev/null searchstr 

# alias which I tab expand then adjust as required
alias zg='zargs **/*.(php|inc|js)~(libs|test|temp|wiki|dompdf)/* -- grep
-i ' 





-- 
zzapper
https://twitter.com/dailyzshtip


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

end of thread, back to index

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-16 22:44 Glob and grep Nick Cross
2019-12-16 23:10 ` Mikael Magnusson
2019-12-16 23:24   ` Dominik Vogt
2019-12-17  1:20     ` Daniel Shahaf
2019-12-17  7:31       ` Nick Cross
2019-12-17  7:31   ` Nick Cross
2019-12-17  9:39     ` Mikael Magnusson
2019-12-16 23:18 ` dana
2019-12-17  7:30   ` Nick Cross
2019-12-17 10:00 ` zzapper

zsh-users

Archives are clonable: git clone --mirror http://inbox.vuxu.org/zsh-users

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.zsh.users


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git