0

I have a root directory that I need to run a find and/or grep command on to return a list of files that contain a specific string.

Here's an example of the file and directory set up. In reality, this root directory contains a lot of subdirectories that each have a lot of subdirectories and files, but this example, I hope, gets my point across.

enter image description here

From root, I need to go through each of the children directories, specifically into subdir/ and look through file.html for the string "example:". If a result is found, I'd like it to print out the full path to file.html, such as website_two/subdir/file.html.

I figured limiting the search to subdir/file.html will greatly increase the speed of this operation.

I'm not too knowledgeable with find and grep commands, but I have tried the following with no luck, but I honestly don't know how to troubleshoot it.

find . -name "file.html" -exec grep -HI "example:" {} \;

EDIT: I understand this may be marked as a duplicate, but I think my question is more along the lines of how can I tell the command to only search a specific file in a specific path, looping through all root-> level directories.

Matt.
  • 1,306
  • 2
  • 13
  • 20
  • I understand this may be marked as a duplicate, but I think my question is more along the lines of how can I tell the command to only search a specific file in a specific path, looping through all root-> level directories. – Matt. Jun 09 '17 at 14:40
  • maybe because there is no match (`-I` means case insensitive), otherwise replacing final `\;` by `+` will launch less processes because of last arg {}, which will be replaced by as many arguments can fit in a command line – Nahuel Fouilleul Jun 09 '17 at 14:58
  • I wrote a recursive bash (tested with sh also) function that traveses a given directory tree and `grep`s files of given name for a given string. See [here](https://stackoverflow.com/a/44461470/4162356). You can modify the `grep` command to match your needs. – James Brown Jun 09 '17 at 15:23
  • What's wrong with that `find -exec grep` you have? I can't really see why it wouldn't work. – ilkkachu Jun 10 '17 at 18:50

1 Answers1

0

find ./ -type f -iname file.html -exec grep -l "example:" {} \+;

or

grep -Rl "example:" ./ | grep -iE "file.htm(l)*$" will do the trick.

Quote from GNU Grep 2.25 man page:

  -R, --dereference-recursive
         Read all files under each directory, recursively.  Follow all symbolic links, unlike -r.

  -l, --files-with-matches
         Suppress normal output; instead print the name of each input file from which output would normally have
         been printed.  The scanning will stop on the first match.

 -i, --ignore-case
         Ignore case distinctions in both the PATTERN and the input files.

 -E, --extended-regexp
         Interpret PATTERN as an extended regular expression.
  • This would read _all_ files in the directory tree, even though we're only interested in those with a known name. There might be lots of other files, too. – ilkkachu Jun 10 '17 at 18:52
  • The `grep | grep` solution will print out only the files that match `file.htm(l)*$` pattern. It comes to be just about 20% slower then `find`. Edited answed with `find` snippet – themeasure43 Jun 11 '17 at 11:22