Find returns results but grep doesn't ?

Asked by Peter R

If I do a Kfind on a directory and include sub paths, for a string "guitar" I get the expected results.

If I use grep on exactly the same directory, in a terminal, I get no results. The grep command is

grep -i -r "guitar" *.txt

is this a bug or is there something wrong with the grep format ?

Question information

Language:
English Edit question
Status:
Solved
For:
Ubuntu grep Edit question
Assignee:
No assignee Edit question
Solved by:
Ralph Corderoy
Solved:
Last query:
Last reply:
Revision history for this message
Ralph Corderoy (ralph-inputplus) said :
#1

You are entering that line at the shell. The shell is expanding 'globs', or filename wildcards, and you have some matching *.txt in that top directory. Thus grep is run as 'grep -i -r "guitar" foo.txt bar.txt' and searches just those two text files. Neither are a directory so it doesn't recurse into them.

'grep -ri guitar .' would work, '.' is the current directory and grep will recurse from there downwards. As '.' is the default for -r it can be omitted: 'grep -ri guitar'.

Revision history for this message
Peter R (forums-oygle) said :
#2

Thanks Ralph for your reply. The problem with doing it that way is two-fold:

1. It takes a very long time as that directory is over 18 Gb
2. The results are very hard to read, because there are audio and video files and the output contains a lot of garbage.

I simply need grep to only go through with a wildcard of '*.txt' and for it to be recursive.

Thanks :)

Revision history for this message
Best Ralph Corderoy (ralph-inputplus) said :
#3

grep doesn't offering filtering of recursive searches. The Unix philosophy is for a tool to do one thing , and one thing well. These tools are then combined in more powerful ways that could be achieved if every tool tried to anticipate all needs. These days, you've two options.

Turn on bash's support for the `**' glob, that means zero or more directories, and don't use grep's recursion since the shell will be giving it an explicit list of txt files.

    shopt -s globstar
    grep -i guitar **/*.txt

That can fail to run grep if the shell finds too many txt files, or their overall length as filenames is too long. Then grep needs running once for each batch of filenames, and find(1) can do that.

    find -name '*.txt' -exec grep -Hi guitar {} +

The -H is needed because find might call grep with only one filename on the last of the runs and you wouldn't know where the matched lines originated as grep only prints the filenames when given more than one file to search.

Note the quotes around '*.txt'. They're needed because you don't want the shell to expand the glob to just those filenames in this directory. You instead want find to be pass that literal string of characters and then it does the comparison as it recurses.

Revision history for this message
Peter R (forums-oygle) said :
#4

Thanks Ralph Corderoy, that solved my question.

Revision history for this message
Peter R (forums-oygle) said :
#5

Thanks Ralph, your reply was very helpful. It worked just fine, thanks. :)