Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

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

Better to explain on examples.

I can:

find . -name "*.py" -type f > output.txt

But how can I store the output to the same file for:

find . -name "*.py" -type f -exec grep "something" {} \

I can't just do

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
share|improve this question
up vote 42 down vote accepted

If I understand you correctly this is what you want to do:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Find all files with extension py, grep only rows that contain something and save the rows in output.txt. If the file contains anything it will be replaced.

Edit: Using -exec:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

I'm incorporating Chris Downs comment here. The above command will result in grep being executed as many times as find finds occurences. However, if you replace the ; with a +, grep is called with the output from find concatenated (up to a certain limit). See question Using semicolon (;) vs plus (+) with exec in find for more on the subject.

share|improve this answer
Use + instead of \;, it will improve execution time significantly (since it will contatenate arguments prior to execution until ARG_MAX). – Chris Down Nov 6 '11 at 14:31
Now I understand the power of xargs! Thanks! – domih Apr 6 at 8:45

If you want to save all the matching lines across all files in output.txt, your last command does work, except that you're missing the required ; at the end of the command.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

If you want each run of grep to produce output to a different file, run a shell to compute the output file name and perform the redirection.

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;
share|improve this answer
the last one really nice :D – bakytn Sep 20 '11 at 3:32
To expand on @gilles answer to make it a little more informative, especially if the list of files you're dealing with is large, you can report the file name (relative path) of each file along with the grep'ed results using this: find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt And if you'd like to see the line numbers of the grep'ed lines you can, of course, use grep -n "something" – JJMpls Jul 24 '14 at 2:27

Use tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

The caveat, is if you have any files with special characters (including spaces) that xargs and grep won't work well with (a file.txt will be interpreted as two files, a and file.txt). The alternative to that is to use either the -x or -print0, but either of those will pollute your output.txt. The -x will use \ to escape certain special characters and this will be in output.txt. The -print0 will use a null byte as a field separator (which also requires xargs -0) and output.txt will look like one long contiguous line of text.

How you deal (or don't) with this is up to you.

share|improve this answer

Your Answer


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

Not the answer you're looking for? Browse other questions tagged or ask your own question.