LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 06-15-2011, 06:07 PM   #1
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Rep: Reputation: Disabled
grep recurse


On the Net I can find plenty about recursive grep but
I cannot find a reply to a specific query.

It's GNU grep, ubuntu 11.04, test directory /opt/test/, all
the directories in this branch have 777 permission, all the
files in the branch have 666 permission and I'm using root
privileges anyway. No access issue here.

The following works recursively:

(a) grep -r 'char' /opt/test/*

The following works on /opt/test/ only, does not recurse:

(b) grep -r 'char' /opt/test/*.c

I'm not looking for a work-around like find/xargs/grep or
find/exec/grep. I already know about them. It is not in the
man-page and I want to know why (a) works and (b) doesn't.

Thanks!


frankl
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 06-15-2011, 06:19 PM   #2
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Quote:
Originally Posted by frankl View Post
On the Net I can find plenty about recursive grep but
I cannot find a reply to a specific query.

It's GNU grep, ubuntu 11.04, test directory /opt/test/, all
the directories in this branch have 777 permission, all the
files in the branch have 666 permission and I'm using root
privileges anyway. No access issue here.

The following works recursively:

(a) grep -r 'char' /opt/test/*

The following works on /opt/test/ only, does not recurse:

(b) grep -r 'char' /opt/test/*.c

I'm not looking for a work-around like find/xargs/grep or
find/exec/grep. I already know about them. It is not in the
man-page and I want to know why (a) works and (b) doesn't.

Thanks!


frankl

Hi,


The problem is the wildcard ... the shell beats grep to it,
so what grep gets presented with to look through is a list
of all .c files in the current directory. As these are files
a recursion obviously makes no sense. Your only solution is
indeed a) a workaround with 'find' or b) removal of any .c files
in the directory you start your search in.



Cheers,
Tink
 
Old 06-16-2011, 04:08 AM   #3
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Original Poster
Rep: Reputation: Disabled
semi-solved

Thanks, Tinkster, the following does work recursively:

grep --include=*.c -r 'char' /opt/test/
 
Old 06-16-2011, 04:22 AM   #4
lugoteehalt
Senior Member
 
Registered: Sep 2003
Location: UK
Distribution: Debian
Posts: 1,215
Blog Entries: 2

Rep: Reputation: 49
Havn't tried it so it's probably bollocks but this seems easier, being more naturally motivated:
Code:
grep -r 'char' /opt/test/*|grep .c
 
Old 06-16-2011, 07:35 AM   #5
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Original Poster
Rep: Reputation: Disabled
Havn't tried it so it's probably bollocks...

>>>
Havn't tried it so it's probably bollocks
>>>

'nuff said.

It works, period. And as I stated in my initial post, I do not need any combos to replace a simple grep.

And no, I do not understand why bash would interfere when the file specification is "*.c" but not when the file specification is "*".
 
Old 06-16-2011, 08:05 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,256

Rep: Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686Reputation: 2686
Quote:
And no, I do not understand why bash would interfere when the file specification is "*.c" but not when the file specification is "*".
Maybe think of it this way:

* - look at everything, including directories, and then expand to files that can be searched

*.c - expand to all files and folders that end in .c and pass them to grep to be searched
 
Old 06-16-2011, 08:35 AM   #7
Karl Godt
Member
 
Registered: Mar 2010
Location: Kiel , Germany
Distribution: once:SuSE6.2,Debian3.1, aurox9.2+3,Mandrake?,DSL? then:W7st,WVHB, #!8.10.02,PUPPY4.3.1 now:Macpup
Posts: 314

Rep: Reputation: 45
I am guessing , that there are no directories to recuse deeper into called /directory.c .
If you do it like
Code:
grep -r 'char' /etc/*.d
it would go recursive into
/etc/modprobe.d/
/etc/rc.d/
/etc/init.d/
 
Old 06-17-2011, 11:14 AM   #8
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Original Poster
Rep: Reputation: Disabled
proof of the pudding

Thanks grail, thanks Karl. Of course, subdirs in the recursion may match the file specification. Quote from the grep infopage:

>>>
grep -rH 'hello' *.c

which merely looks for `hello' in all files in the current directory whose names end in `.c'. Here the `-r' is probably unnecessary, as recursion occurs only in the unlikely event that one of `.c' files is a directory.
>>>

Well, the proof of the pudding is in the eating. Since file and dir names accept all chars except slash and null, I created directory /opt/test/*.c/ and tried from /opt/test/:

(a) grep -r 'char' *.c

The search went through /opt/test/ and /opt/test/*.c/ as advertised, other directories in the branch didn't match the spec and were ignored.

What works on all subdirs and on c-files only is:

(b) grep -r --include='*.c' 'char' /opt/test/

Both (a) and (b) are derived from the infopage. Note the quotes on the spec.

The infopage is a lot better than the manpage and still not good enough. Too many people are puzzled by grep recurse and embark on find/exec or find/xargs exercises.
 
Old 06-17-2011, 10:02 PM   #9
brasshopper
LQ Newbie
 
Registered: Apr 2004
Location: Boca Raton, Florida
Distribution: Fedora/Redhat
Posts: 8

Rep: Reputation: 3
One thing you have to remember on Unix is that the shell always handles the '*' expansion before the command sees it. You can shield the expansion from the shell with escapes, like \* or '*' but then the command will look for a file named * since that is a legal filename in Unix. No commands do their own expansion in Unix. They do not expect to. The expansion is done by the shell, and a shell can do expansion as they feel like it, so long as the right thing is passed to the command.

People rightly prefer to use solutions like find and xargs rather than recursive grep because those solutions will work for any command. I looked at the options you show to recursive grep, and I thought, "gosh, why would they overload all that crap into grep? Maybe for windows ports, where the proper tools are not available?"

Seriously, the Unix way is to use the general tools and not to load stuff into every command. All a command generally needs to do is to accept a large number of file names on the command line - when you want to dig through a directory, you use find, xargs, and stuff.
 
2 members found this post helpful.
Old 06-18-2011, 04:36 PM   #10
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Original Poster
Rep: Reputation: Disabled
get over it

>>>
Seriously, the Unix way is to use the general tools and not
to load stuff into every command.
>>>

Nothing trumps a passionate declaration of faith. Or maybe
some history?

Once upon time grep didn't have the recurse option. People
were unhappy, competing utilities sprang up - lo and behold
grep got its recurse. Faith couldn't stop the aberration.

My post had two examples:

(a) grep -r 'char' *.c
(b) grep -r --include='*.c' 'char' /opt/test/

Example (a) does not need any replacement with any piping.
Example (b) is shorter and quicker than any piping. It even
has a twin option --exclude which could prove a bit
acrobatic for the pipers.
 
Old 06-18-2011, 05:27 PM   #11
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 13.1
Posts: 1,326

Rep: Reputation: 253Reputation: 253Reputation: 253
brasshopper & frankl: I would say itís personal taste which way you prefer. Both way have pros and cons:

- using only basic options might be more portable across Linux, AIX, BSD, ... On AIX the grep doesnít have the --include option, unless you compile the GNU version on your own.

- using built-in options for extra functionality might execute faster.

On OS X and AIX I have therefore the GNU versions of sed and awk. I prefer the second way and like to get known to options I wasnít aware by this forum or scanning the man pages; and if itís not installed by default I just compile it on my own. But if you have to deliver software to customers the first way may have itís justification as you canít know, what they installed besides the basic stuff.
 
Old 06-19-2011, 09:14 AM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Debian sid + kde 3.5 & 4.4
Posts: 6,823

Rep: Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957Reputation: 1957
We recently had some fun with a bug regarding recursivity in gnu grep:

http://www.linuxquestions.org/questi...ubuntu-875911/
 
Old 06-19-2011, 02:10 PM   #13
frankl
LQ Newbie
 
Registered: Jun 2011
Posts: 6

Original Poster
Rep: Reputation: Disabled
http://www.linuxquestions.org/questi...ubuntu-875911/


Last April, sneakyimp failed to limit a recursive grep in
the branch /var/www/site/ to just PHP files using:

grep -irl --include='*.php' 'car_images' *

Nowhere explained but empirirically true:

* The last grep argument is the file spec when searching flat,
* it is the dir spec when recursing (--include will be ignored)
* it is the search dir when recursing with --include.

Solution for sneakyimp:

grep -irl --include='*.php' 'car_images' /var/www/site/
 
Old 06-19-2011, 02:46 PM   #14
salasi
Senior Member
 
Registered: Jul 2007
Location: Directly above centre of the earth, UK
Distribution: SuSE, plus some hopping
Posts: 4,053

Rep: Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881Reputation: 881
Quote:
Originally Posted by lugoteehalt View Post
Havn't tried it so it's probably bollocks but this seems easier, being more naturally motivated:
Code:
grep -r 'char' /opt/test/*|grep .c
It may not be important in your application, but be aware that 'grep .c' matches anything with .c anywhere in the filename. Now, it is probably unlikely that you have any filenames that end in .creep, but you might have .c.bak, .c.old.somethingelse, and it may not be a problem if you just want to look through the list manually, but if you intend to pass it to something else to delete them, then it might just be a problem.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
scp recurse but NOT overwrite? Goog Linux - Software 3 12-04-2012 09:55 PM
copy command cp -R does not recurse directories ankuryu DamnSmallLinux 1 05-15-2007 07:35 AM
how to recurse a cat? paledread Linux - Software 9 05-20-2006 12:30 PM
Recurse a directory Peter Shepard Linux - General 1 12-23-2005 03:42 PM
recurse through subdirs? Axion Linux - Software 4 02-16-2004 09:12 PM


All times are GMT -5. The time now is 05:03 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration