Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Assuming that the grep tool should be used, I'd like to search for the text string "800x600" throughout the entire file system.

I tried:

grep -r 800x600 /

but it doesn't work.

What I believe my command should do is grep recursively through all files/folders under root for the text "800x600" and list the search results.

What am I doing wrong?

share|improve this question
2  
And by "it doesn't work" you mean exactly what? Does it not print any output, hangs or print lots of Permission denied errors? Did you run it as root or a normal user? –  alex Jul 6 '11 at 7:42
    
I'm getting some traction, first of all I was in my user home directory trying to run the command. So now I've cd / out to root. Next I tried the same command as above and I'm getting a lot of Permission denied errors. Ok, so now I try sudo grep -r 800x600 / and then I get a /proc/sysrq-trigger: Input/output error –  Level1Coder Jul 6 '11 at 8:00
    
Hmm, don't know why it wouldn't work. You may ignore access errors by doing grep -r 800x600 / 2>/dev/null. You can also try running it as root. –  Totor Jan 26 at 1:28

3 Answers 3

up vote 23 down vote accepted

I normally use this style of command to run grep over a number of files:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

What this actually does is make a list of every file on the system, and then for each file, execute grep with the given arguments and the name of each file.

The -xdev argument tells find that it must ignore other filesystems - this is good for avoiding special filesystems such as /proc. However it will also ignore normal filesystems too - so if, for example, your /home folder is on a different partition, it won't be searched - you would need to say find / /home -xdev ....

-type f means search for files only, so directories, devices and other special files are ignored (it will still recurse into directories and execute grep on the files within - it just won't execute grep on the directory itself, which wouldn't work anyway). And the -H option to grep tells it to always print the filename in its output.

find accepts all sorts of options to filter the list of files. For example, -name '*.txt' processes only files ending in .txt. -size -2M means files that are smaller than 2 megabytes. -mtime -5 means files modified in the last five days. Join these together with -a for and and -o for or, and use '(' parentheses ')' to group expressions (in quotes to prevent the shell from interpreting them). So for example:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Take a look at man find to see the full list of possible filters.

share|improve this answer
2  
Note that -xdev will exclude all other filesystems, not just special ones. (e.g., if you have /home mounted as a separate partition, it won't be searched.) –  cjm Jul 6 '11 at 8:29
    
I tried running each one but both return an error -- find: paths must precede expression: / –  Level1Coder Jul 6 '11 at 8:36
    
@Level1Coder my mistake, I had the -xdev option in the wrong spot. I've edited the answer to correct this. @cjm Good catch, meant to say that but forgot by the time I reached the end! –  Richard Downer Jul 6 '11 at 8:43
    
Great, both are working now but I find that the first method is extremely slow. I ran both in 2 different terminals and the efficient one was done in ~1min and the inefficient method was slowly chugging along, I didn't even allow it to finish and just ^C out. Now that this works, is it possible to make it a bit more specific, such as only search text within files that are of filetype .txt, less than 2MB and modified within the last 5 days? –  Level1Coder Jul 6 '11 at 16:27
1  
Note: When regular expressions aren't required 'fgrep' is significantly faster than 'grep', which will make a big difference if you're searching a large tree. –  Nathan Kidd Jul 6 '11 at 18:56

For simplicity, I would suggest ack-grep .
Link shows many cases when ack-grep is a better option.

To use is, after install,
ack-grep pattern /

share|improve this answer
    
Thanks for recommending this, but I ran this and it didn't really give me the search results I anticipated. Seems like I will need to tweak many settings to get what I want. As of now Richard's answer works right out of the box. Will look into this in the future as it seems useful as well. –  Level1Coder Jul 6 '11 at 17:30

Normally you wouldn't want to actually search EVERYTHING on the system. Linux uses file nodes for everything, so some "files" are not things you would want to search. For example /dev/sda is the physical block device for your first hard drive. You probably want to search the mounted file systems not the raw disk device. Also there is /dev/random which spits out random data every time you read it. Searching that doesn't make a lot of sense. The /proc file system is also problematic in your case.

I would recomend one of two things.

  1. Don't search at root, only search the places that might be useful. Search /home or /usr or /etc separatly. The info you are looking for is likely of a specific type, so it's likely to be in a specific folder anyway. Configuration settings should be in /etc. Your personal data files should be in /home. Limiting search to a major area like this will greatly reduce your problems with recursive greps.

  2. Exclude problematic areas using --exclude-dir and a set of things you know you don't needlike this:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Lastly, it's not uncommon to run across a few 'permission-denied' errors when doing a big recursive grep. In the normal course of use there are files your user may not be able to read. As long as these are just a few odd files and not things like the raw device for your hard drives or the entire proc file system, it's ok to just ignore the errors. In fact you can do this on the command line by sending all the errors into never never land:

grep -r search_string /path 2> /dev/null
share|improve this answer
    
good tips and advice –  Level1Coder Jul 6 '11 at 17:26
1  
-I to exclude binary –  Rahul Patil Mar 31 at 11:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.