Linux - NewbieThis 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
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
The OS is Centos
Edit: I am reasonably sure I am using BASH. The command line prompt is the dollar sign.
Core question: How to grep recursively?
Edit: Post 4 looks like the best answer, worked for me
Prerequisites: I did look at the man page and as I read it, this should work. The same for several google searches. I clicked the Search box here, entered "grep", clicked Go, and absolutely nothing. I am in a government installation, go thorugh their firewalls, and that has been a problem in the past.
When I run a grep and the requested string is found in the current directory, each instance is returned. When I move up a directory and add a -r or a -R, nothing is returned. The response is: No such file or directory. This is the command:
Code:
grep -r Open *.cpp
I have tried this in the lower level directory.
Code:
find . -name *.cpp
It finds the files. So do this, again, in the lower level directory where the files do reside:
Code:
find . -name *.cpp | grep Open
The response is nothing. I am using this to find the ultimate source of some declarations. Sometimes I must go through multiple include files before finding what I really need.
Your advise please.
Last edited by bkelly; 03-11-2019 at 02:54 PM.
Reason: note where to find the answer.
I am confused; what exactly are you looking for? File/directory with certain characters in their name?
Or looking for certain characters within file(s)?
I am confused; what exactly are you looking for? File/directory with certain characters in their name?
Or looking for certain characters within file(s)?
I am looking for the files that have the text "Open" in them. I do the search again for the .h files to find where something is declared.
When I don't find the declaration, move up one directory level and do a recursive search on the .h files.
If not found one level up, go another level up.
...grep -r will not really work with files (like *.cpp). ...
I do not understand what you intend by that. My current understanding is that in Linux the characters ".cpp" on the end of the file name are just a few more characters on the end. They have no effect on the significance of the file. I use that to limit my search. I look for how it is used by specifying *.cpp and for where it is declared by using *.h. From your post I infer that might not be valid.
I do not understand what you intend by that. My current understanding is that in Linux the characters ".cpp" on the end of the file name are just a few more characters on the end. They have no effect on the significance of the file. I use that to limit my search. I look for how it is used by specifying *.cpp and for where it is declared by using *.h. From your post I infer that might not be valid.
recursive means walk inside dirs. If you specify files there are no dirs to go thru.
So
Code:
grep -r 'pattern' <dir[s]>'
or
grep 'pattern' <filelist>
That seems to be strange.
I neglected to mention that I think the shell is bash, the command prompt is the dollar sign.
That will work. But, gosh, seems like the -r or the -R should work. Those would be much easier.
EDIT: IMPORTANT: I have discovered that my quotes problem was caused by manually copying the command into Libre Writer as a place to save it. When I did that edit, Writer replaced the Linux style quotes (right phrase) with open and close document style quotes. Those don't work so well. I am now sure the original was and is fine. What was back up in #4
i think the problem is that the shell expands the '*.cpp', so grep effectively gets a list of filenames, and does not recurse anywhere.
it would be interesting to test if the results are different whether there's cpp files in the current directory or not.
btw, i'm pretty sure
Code:
grep -r Open
would work on recent grep verisons, however it would then search ALL files recursively.
if you need to limit this to cpp files, you need to use one of the find/grep constructs suggested by others here.
Quote:
Originally Posted by bkelly
That seems to be strange.
I neglected to mention that I think the shell is bash, the command prompt is the dollar sign.
That will work. But, gosh, seems like the -r or the -R should work. Those would be much easier.
strange for you, business as usual for others.
maybe would be easier for you, more difficult for others.
btw, the dollar sign says nothing about the shell you use.
recursive means walk inside dirs. If you specify files there are no dirs to go thru.
So
Code:
grep -r 'pattern' <dir[s]>'
or
grep 'pattern' <filelist>
I don't agree with that. By specifying a file limitation, such as *.cpp, to me, that means to conduct the search but limit it to the files specified. I think it should work not only in the current directory, but with the -r or -R, work in all the subdirectories.
As noted, and as I read the man page, it should work.
My grep only worked using the -r and then only the search string.
Code:
$ grep -r <pattern>
The directory is managed by Git and because of this, there is information which grep found that I don't need to see.
The only way I could get it to work was to use */*.c or */*/*.c, thus forcing me to know the depth of the tree, and/or overlooking whether or not there were lesser or greater depth files in there which were being overlooked.
This reminded my why, so very long ago, I forsook the use of grep -r
I don't agree with that. By specifying a file limitation, such as *.cpp, to me, that means to conduct the search but limit it to the files specified. I think it should work not only in the current directory, but with the -r or -R, work in all the subdirectories.
As noted, and as I read the man page, it should work.
you don't agree and you think it should... yet that is not how grep works. your computing life will continue to be unpleasant if you cannot adjust to how programs work...
of course you can always file a bug against grep's disagreeable behavior and see what the devs have to say about it.
if you do please make sure to share a link here!
btw:
Quote:
Originally Posted by man grep
If no FILE is given, recursive searches examine the working directory
you don't agree and you think it should... yet that is not how grep works. your computing life will continue to be unpleasant if you cannot adjust to how programs work...
of course you can always file a bug against grep's disagreeable behavior and see what the devs have to say about it.
if you do please make sure to share a link here!
btw:
weirdly phrased, but there it is.
Aww, if only I could copy paste from my working computer to here. Regardless, my man page, from Centos, states:
Quote:
grep searches the named input FILEs (or standard input if not files are named, or if a single hyphen-minus (-) is given as file name) for lines containing a match to the given PATTERN. By default, grep prints the matching lines.
Those words do not imply that if a file specification is provided then the recursive option will not work. I scrolled down some to look at the -r and -R option and neither one had anything to say about file specifications and how the recursion would not be performed when an file specifier is used. Therefore, I claim that to say it should work is a reasonable conclusion. Stating that does not mean I cannot adjust, but it is a valid observation.
The OS is Centos
Edit: I am reasonably sure I am using BASH. The command line prompt is the dollar sign.
Core question: How to grep recursively?
It
Code:
grep -r Open *.cpp
I have tried this in the lower level directory.
Code:
find . -name *.cpp
The thing is that "*.cpp" is evaluated BY the shell in the current directory only, before grep gets passed the commandline.
So grep will search recursively for the .cpp files that have the same name as the ones IN that current directory (no others).
As you went one dir upwards there were no .cpp files in that directory thus grep didn't have any filenames to search for.
You will need something like find to expand your (quoted) wildcards.
You must always remember that most programs in Linux (and in fact Unix) do not do their own wildcard (*, ? etc) handling, they let the shell (bash or whatever) do that for them, so "*.cpp" means: all of the .cpp files in the current directory (and */*.cpp all of them ONE single directory deeper). The find program is one of the exceptions, it can do its own wildcard expansion, as long as the wildcard IS protected from the shell (by backslash or quotes). So
Code:
find . -name "*.cpp"
will find all .cpp files in the whole tree of directories from the current one downwards and the -exec will then execute the grep command ON them.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.