Fog Creek Software
Discussion Board




Searching on a Unix/Linux box

What is the best way to search for a string in a file or in the file name, from the top level on a Unix box?

i.e. lets say I am at the top most directory level "/"

And I would like to search for "cvs" either in a file or in the file name - but I have no idea which directory this is located.

A caveat is the serach must not hog up CPU.

'grep' seems like a good way to search within a folder - but I am not sure how, if possible, it can be used to search across all folders (and sub-folders)

NutCracker
Tuesday, August 03, 2004

find . -name cvs

will find everything with "cvs" in its name (I think -- or maybe you need to add wildcards if you want "cvs" as a substring and not just the whole string)

Ryan
Tuesday, August 03, 2004

http://www.athabascau.ca/html/depts/compserv/webunit/HOWTO/find.htm

Code Monkey
Tuesday, August 03, 2004

grep -ri cvs /

That will find all files containing the string CVS that you can read, recursively, and ignoring case.  It will also show you the matches.  Add -l (thats a lowercase L) to just list the filenames, and not the actual line that matches.

To find the files, the previous poster that mentioned find was correct.  Though if you're on a more current system, 'locate' might be installed and will be about 1000 times faster.

locate cvs

will probably work better than find.

Andrew Hurst
Tuesday, August 03, 2004

You don't want to start from the root. It will search far too much and take forever. Think about where you really want to direct the search first. For instance, if I go to / on my unix box to start I cold be searching the nfs mounts of 10 other unix machines before I ever even reach my own /usr. That can be 20-30-40 Gb of crap I didn't really intend to look through, not to mention the network latency slowing me down.

old_timer
Tuesday, August 03, 2004

find / -type f | xargs grep cvs

and

find / -name "*cvs*"

Coder
Tuesday, August 03, 2004

> find / -type f | xargs grep cvs

This may just be an issue of style, but I prefer to use the -exec parameter of "find" rather than piping it through xargs - xargs will complain if the find command doesn't return anything, whereas -exec will be silent:

find / -type f -exec grep -i cvs

(note that this only searches for the string within files - you'd need the other command specified above to look for the filenames)

- former car owner in Queens
Tuesday, August 03, 2004

Adding to what old_timer said - unless you're root, starting a recursive search from /you're also liable to get TONS of error messages for all the directories where you don't have rx permissions.

- former car owner in Queens
Tuesday, August 03, 2004

Ok, in that case...

find / -type f -exec grep -i cvs 2>/dev/null

DoomedToFail
Tuesday, August 03, 2004

In windows it's enough to right-click on My Computer and click search.

What a wonderful world :)

 
Tuesday, August 03, 2004

find somedir -type f -exec egrep -H -i pattern {} \; has the side effect of showing which file matched your pattern.

Recursive grep is nowhere near standard (dammit), so I've aliased the above command.  I also have variants, things like:

find somedir -name \*.c -exec egrep -H pattern {} \; will search my source files (I don't like -i in this case).  You can also do stuff like find somedir \( -name \*.c -o -name *.cc -o -name \*.cpp \) egrep etc etc to search all your .c, .cc, and .cpp files.

I spend way too much time in the shell.....

Snotnose
Tuesday, August 03, 2004

Likewise in Konqueror you go to the root directory and in the tools menu choose 'find file' . It has all the options you need.

Andres
Tuesday, August 03, 2004

Starting a separate grep for each file using -exec is slow, but using xargs can fail when you have whitespace in the filename, so try this:

(find / -type f -print0 | xargs -0 grep cvs) 2> /dev/null

This uses the null character to separate filenames, as it is actually the only character that cannot appear in a filename on a Unix system.

You may also want to use the -i option for grep to ignore case, and similarly -iname for find when searching for cvs in the filename.

Tim Evans
Tuesday, August 03, 2004

If you just want to look for filenames an alternative is to use "locate cvs", which looks in a database instead of scouring the disk. It's much more efficient. However you need to run "locate -u" to update the database periodically and it will miss new files that haven't been indexed since the last update.

_
Tuesday, August 03, 2004

install 'locate' if you do not already have it

Tom VU
Tuesday, August 03, 2004

I have observed that xargs can be MUCH faster than find  -exec.

Jerry
Tuesday, August 03, 2004

Tim Evans, Jerry et al:

Thanks for the tips - maybe I need to give xargs another try.

(and I'm embarassed that I forgot the {} \; to terminate the sample -exec statement I posted)

- former car owner in Queens
Wednesday, August 04, 2004

"In windows it's enough to right-click on My Computer and click search"

...and it's a crap shoot as to whether it will actually find what you are looking for, not to mention that your options with "find" and "grep" are *much* more flexible that what Windows gives you.

AMS
Wednesday, August 04, 2004

AMS:

click the "advanced" tab... gives you pretty much the same options as unix... by file type/name/date modified/created.. if nothing else download cygwin and put the "bin" dir in your MS Windows path and you can use whateva unix tools you like on your Windows file system...

PopCulture
Friday, August 06, 2004

*  Recent Topics

*  Fog Creek Home