Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am working on an ancient UNIX whose grep lacks the -r/--recursive option.

I need to find an error that our application is causing, but I do not know which log file our application is writing errors to. However, I do know that the log file is somewhere in /opt. So I want to find FooErrorMessage under /opt in *.log. Here's what I tried:

find /opt | xargs grep FooErrorMessage

-- but this does not work, and I don't know where to specify that I just want *.log files in the command.

share|improve this question
up vote 5 down vote accepted

You're just trying to find all log files under /opt and search them for somethnig_I_am_looking_for right? Why not:

find /opt -name '*.log' | xargs grep something


find /opt | grep .log | xargs grep something


Oh, and since I can't figure out how to comment on the other answers: be careful with *.log as the shell will interpret that as globbing, and match all files in the current directory that end in .log . You should use either \*.log or '*.log'

share|improve this answer
\\*.log or "*.log" – dotjoe Jul 30 '09 at 21:32
dotjoe - be careful with double-quotes. The shell interprets stuff inside double quotes. Single quotes prevent interpretation. – atk Jul 31 '09 at 1:30

Beware of filenames with spaces in them, as it is allowed by Unix; xargs will choke on them. Use find /opt -name '*.log' ... -print0 | xargs -0 grep ..., these options are meant to go together.

Also, grep or your shell might have a limited number of arguments, and the list of files returned by find might exceed that. Use the -n number option of xargs to run grep by chunks of number files.

share|improve this answer
+1 for 'find ... -print0 | xargs -0 ...'. The operating system will limit the total length of the arguments (and the size of the environment also comes out of the same space - so lots of environment variables reduces the number of arguments you can use), but xargs should be attuned to the o/s limit and not create overlong argument lists. Certainly, I don't recall that being a problem ever. – Jonathan Leffler Jul 31 '09 at 5:04

do you have perl?

try --

share|improve this answer
I use Ack every day. I especially like the smart-casing option. – koenigdmj Jul 31 '09 at 3:01

find /opt -type f -name *.log -print | xargs grep 'something_I_am_looking_for'

share|improve this answer
You need quotes around '*.log' to be safe. (And, as written, you do not need quotes around 'something_I_am_looking_for', but it is likely better to include them than omit them - certainly in general. – Jonathan Leffler Jul 31 '09 at 5:01

Apart from adding the "-name '*.log'", try adding -n1 to xargs.

Maybe your ancient grep can't take multiple input files, so -n1 will run grep for each of those files, instead of passing them as arguments at once

share|improve this answer

You can also do this with the exec option to find instead of xargs

find /opt -exec grep "thing you are looking for" {} \;

share|improve this answer
That launches a command for each file found - that gets expensive by comparison with using xargs. – Jonathan Leffler Jul 31 '09 at 5:05

GNU grep has its own “recurse” option:

 grep -R foo /path/to/directory

To grep files of a particular pattern, you’re best off with find and xargs:

 find /path/to/directory -name \*.log -print0 | xargs -0 grep foo
share|improve this answer
find /opt -name *.log | xargs grep yourstring
share|improve this answer

Unless you have subdirectories that are many levels deep, grep *, grep / and grep //* is easy to remember and hard to type wrong...

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.