Click to See Complete Forum and Search --> : find -exec and grep


TreeHugger
12-13-2002, 10:37 AM
I used to do this all the time but haven't touched it for a couple of years: how do I do a search over a directory & sub-dirs to parse all text files with grep for a certain string?

I get an 'exec missing arg' message with this:

find . -name "*log" -exec "cat {} | grep ejbCreate \; "

where ejbCreate is the text I'm looking for.

Ideally I would also like to get it to output the filename as well, but first I'd like to see if the text is there at all anywhere.

TIA

Energon
12-13-2002, 11:10 AM
the -R option with grep goes into subdirectories. No need to use find at all.

TreeHugger
12-13-2002, 11:38 AM
OK. But I can't make it work. It says the same in the man page, but I don't get any results, not even checking for something that I know is there:

grep -R "transparent" *.log

Any advice?

bwkaz
12-13-2002, 02:18 PM
Originally posted by TreeHugger
find . -name "*log" -exec "cat {} | grep ejbCreate \; " Your \; has to be outside the quoted string, I think.

You can't really use a recursive grep, because that only works (in my experience -- which doesn't mean that I'm not wrong, of course) when the directories are named the same as the files you want to grep through. For example, a grep -r ejbCreate * would work, but would search through every file. grep -r ejbCreate *.log will only descend directories that end in .log.

In the end, you need something like find . -name '*.log' -exec "grep ejbCreate {}" \; -- it is also interesting to note that you don't need the extra "cat" process for each file, just a simple grep will work fine.

uptimenotifier
12-14-2002, 08:27 AM
Try:

find . -name "*log" -type f -exec grep ejbCreate {} \;

TreeHugger
12-15-2002, 09:31 AM
Great! That works. Plus with the -H option on grep, it gives the file name too.

I don't know why, but I can't use """ in the exec statement. The following:

find . -name "*log" -type f -exec "grep ejbCreate {}" \;

gives the following error on every file it finds:

grep ejbCreate ./filename: no such file or directory

I can drop the quotes and it works, but I'm interested to know why - in the man page, it says you might have to use quotes.

Thanks

bwkaz
12-17-2002, 11:16 AM
I think it's because the find command is taking everything inside the quotes as one command name to run. The reason the \; is needed, is so that the -exec predicate to find knows where the end of its command is. Which means that it understands what to do if you don't escape the spaces. Which probably means that if you escape the spaces anyway (quotes effectively just escape the spaces), it will interpret the whole thing as one word, and search for a command to run named the same as that whole thing. There is no command on your system named grep\ ejbCreate\ ./filename, so the shell tells you that.

Omitting the quotes makes find invoke just grep, with the other words as arguments. With the quotes, there would be no arguments.

TreeHugger
12-17-2002, 12:07 PM
thanks. That makes sense.