18

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.
  • 8,016
  • 6
  • 40
  • 62
Pandu
  • 189
  • 1
  • 2
  • 7

3 Answers3

19

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
  • 5,351
  • 1
  • 16
  • 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
13

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
  • 275,237
  • 103
  • 548
  • 598
  • 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
1

Exclude directory warnings in grep with the --exclude-dir option:

grep --exclude-dir=* 'search-term' *

Just look at the grep --help page:

--exclude-dir=PATTERN directories that match PATTERN will be skipped.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133