16

I use the following command to find a string recursively within a directory structure.

find . -exec grep -l samplestring {} \;

But when I run the command within a large directory structure, there will be a long list of

grep: ./xxxx/xxxxx_yy/eee: Is a directory
grep: ./xxxx/xxxxx_yy/eee/local: Is a directory
grep: ./xxxx/xxxxx_yy/eee/lib: Is a directory

I want to omit those above results. And just get the file name with the string displayed. can someone help?

Jose Ricardo Bustos M.
  • 7,881
  • 6
  • 39
  • 58
Pandu
  • 169
  • 2
  • 7

2 Answers2

16

grep -s or grep --no-messages

It is worth reading the portability notes in the GNU grep documentation if you are hoping to use this code multiple places, though:

-s --no-messages Suppress error messages about nonexistent or unreadable files. Portability note: unlike GNU grep, 7th Edition Unix grep did not conform to POSIX, because it lacked -q and its -s option behaved like GNU grep’s -q option.1 USG-style grep also lacked -q but its -s option behaved like GNU grep’s. Portable shell scripts should avoid both -q and -s and should redirect standard and error output to /dev/null instead. (-s is specified by POSIX.)

stevesliva
  • 4,965
  • 1
  • 15
  • 39
  • I don't think it is useful to hide errors, when you can avoid them. See my answer – fedorqui Mar 07 '17 at 21:51
  • 2
    Finally! The correct answer to this question! When you are interested in only seeing the grep 'hits' and not all the un-useful trash like 'Is a directory' this is the way to do it. I've been trying to use -v to suppress anything with 'directory' in it - but it's obvious now why that won't work: these 'Is a directory' are messages not the grep results themselves. – kevdev May 03 '19 at 21:14
12

Whenever you are saying find ., the utility is going to return all the elements within your current directory structure: files, directories, links...

If you just want to find files, just say so!

find . -type f -exec grep -l samplestring {} \;
#      ^^^^^^^

However, you may want to find all files containing a string saying:

grep -lR "samplestring"
fedorqui
  • 252,262
  • 96
  • 511
  • 570
  • 5
    `find -type f` and `grep -r` or `grep -R` are good choices... just to complete the answer, perhaps add that `-d skip` specifically takes care of `Is a directory` issue... it is useful at least in cases like using shell options for recursive search, for ex: `grep -d skip -l 'samplestring' **/@(*.txt|*.log)` – Sundeep Mar 08 '17 at 05:14
  • 1
    @Sundeep nice! I wasn't aware of the `-d` flag. – fedorqui Mar 08 '17 at 14:34
  • Look here https://stackoverflow.com/questions/7131670/make-a-bash-alias-that-takes-a-parameter to create a function in your `.bashrc` to do this, so you only need to supply `samplestring` – PfunnyGuy Jul 29 '21 at 17:07