66

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?

3
  • 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, 2011 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 Jul 6, 2011 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, 2014 at 1:28

8 Answers 8

92

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.

12
  • 3
    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, 2011 at 8:29
  • I tried running each one but both return an error -- find: paths must precede expression: / Jul 6, 2011 at 8:36
  • 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. Jul 6, 2011 at 18:56
  • 1
    You can avoid going through xargs with maybe better efficiency by doing find / -xdev -type f -exec grep -H '800x600' +.
    – Totor
    Jan 26, 2014 at 1:31
  • 3
    No, the + sign at the end of the find command actually does the same thing as xargs: it spawns one grep process with several arguments.
    – Totor
    Jan 27, 2014 at 12:58
17

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
1
  • 3
    -I to exclude binary Mar 31, 2014 at 11:16
3

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 /
1
  • 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. Jul 6, 2011 at 17:30
2

Another way of looking at it is this way:

grep -r /* | grep "800x600"
1

If you want to run search for a text only in files matching a specific name pattern (e.g. .txt files) you can do:

grep -rlw --include="*.txt" -e "text to search" path/to/dir

Omit the w option if you also want to find files where the search text is a substring of the file content.

1

I use the following (remind "sir"):

grep -sIr --exclude-dir={dev,proc,run,sys} "800x600" /
  • s suppresses error messages like non-existent or unreadable files
  • I ignores binary files
  • r enables recursive search
  • Sometimes i to search case-insensitive
  • Sometimes l to display only the filename

Alternatively to search in all files except mounts (grep sadly does not have an --one-file-system option):

find / -xdev -exec grep -sIril "800x600" "{}" \;
1
0

*then I get a /proc/sysrq-trigger: Input/output error

Your command is working. You are getting this error because you are trying to scan running processes for a string.

I recommend excluding system directories with

grep --exclude-dir={proc,sys}  "800x600" /
1
  • according to man grep it is --exclude-dir= with two leading minus
    – fraleone
    Mar 20, 2020 at 6:41
-5

simply right-

grep -r "800x600" /

-What is wrong in your current command is the quotes, "". Always put the string argument to grep in quotes.

1
  • 6
    This is not the problem here. You do not need quotes when giving this particular type of argument to grep. Try it and you'll see. Put the string "800x600" in a file and then grep 800x600 file and you'll see it works just fine. The OP is obviously having some other issue.
    – slm
    Jul 1, 2015 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .