Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:

(a) 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?

(b) 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 ./*?

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


My machine is an Ubuntu 14.04, 64-bit. The output of grep --version is:

grep (GNU grep) 2.16
Copyright (C) 2014 Free Software Foundation, Inc.
share|improve this question
    
Also you're relying on the shell expanding wildcards such as *, known as globbing. Globbing does not include filenames starting with a dot such as .bashrc as standard. You can set shell options so that it will include these files, but you can get yourself in a bit of a mess if you don't know what you're doing. A good guide to understanding globing can be found here mywiki.wooledge.org/glob – Arronical 6 hours ago
    
I dunno why, but I've always done globbing on hidden files, and it has always worked. I haven't change any setting or something. As I pointed out in (2), it works with grep "string" .bash* too. – John Red 6 hours ago
    
Sorry, my last example was incorrect. You can search in hidden files as well, and suppressing the "is a directory" because Linux technically sees directories as a different type of file. The command would be then: grep "string" * .* 2>/dev/null or grep -s "string" * .* – Terrance 5 hours ago
up vote 4 down vote accepted

A glob will not expand into hidden files, as @Arronical and @Terrance already mentioned in comments. 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 the option -d skip, as @anonymous2 mentioned, but on my system I also get the error grep: .gvfs: Permission denied, so I suggest using the option -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, use grep -s "string" /path/to/dir/{*,.*}

share|improve this answer

You need the -d skip option added on.

a) Grep is searching inside of files. You can search recursively, as you said, if you want to search files inside of a directory.

b) By default, grep will read all files, and it detects the directories. Because by default you have not defined what to do with the directories with the -d option, it give error output.

c) Searching just within the parent directory would be `grep -d skip "string" ./*

share|improve this answer
    
For more information on grep, see man grep. – anonymous2 6 hours ago
    
(a) Please see the edit. (b) Using -d skip does not work; it's basically the same as -s; also, see the edit. (c) Nope, grep -d skip "string" ./* does not work either. – John Red 6 hours ago
1  
@JohnRed If I understand right, you should be using grep -s "string" * .* or grep -d skip "string" * .* – wjandrea 5 hours ago
    
@wjandrea, you are correct! The problem, as it turns out, is with globbing. Just * does not include hidden files, but .* gives us the hidden files as well. I find this behavior weird. But, even so, giving both * and .* as parameters includes the non-hidden and well as the hidden files. Could you post this as an answer? – John Red 4 hours ago

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.