Ubuntu – How to use grep on all files non-recursively in a directory


I want to search for a string of text in all files in a directory (and not its subdirectories; I know the -r option does that, but that is not what I want).

  1. Running

    grep "string" /path/to/dir

    is supposed to be able to do this, I've read, but it gives me the error:

    grep: dir: Is a directory

  2. Next, I tried running grep on multiple files.

    grep "string" .bashrc .bash_aliases works perfectly.

    grep "string" .bash* works as intended too.

    grep "string" * gives me the errors:

    grep: data: Is a directory
    grep: Desktop: Is a directory
    grep: Documents: Is a directory
    grep: Downloads: Is a directory

Only the errors are printed, I don't get the matching lines. I tried using the -s option, but to no avail.

So, my questions:

  1. Why am I not being able to use grep on a directory, as in (1), when I should be able to? I've seen that done in plenty examples on the Internet.
    Edit: When I say "using grep on a directory", I mean "search in all the files in that directory excluding its subdirectories". I believe that this is what grep does when you pass a directory to it in place of a file. Am I incorrect?

  2. Please give me an explanation on the workings of grep that would explain the behavior of commands in (2).
    Edit: Let me be more specific. Why does using wildcards to specify multiple files to search in for work with .bash* and not with * or even ./*?

  3. How can I search all the files in a directory (and not its subdirectories) using grep?

Best Answer

In Bash, a glob will not expand into hidden files, so if you want to search all the files in a directory, you need to specify hidden files .* and non-hidden *.

To avoid the "Is a directory" errors, you could use -d skip, but on my system I also get an error grep: .gvfs: Permission denied, so I suggest using -s, which hides all error messages.

So the command you are looking for is:

grep -s "string" * .*

If you are searching files in another dir:

grep -s "string" /path/to/dir/{*,.*}

Another option is to use the dotglob shell option, which will make a glob include hidden files.

shopt -s dotglob
grep -s "string" *

For files in another dir:

grep -s "string" /path/to/dir/*

† Someone mentioned that I shouldn't get this error. They may be right - I did some reading but couldn't make heads or tails of it myself.