Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

3 Answers 3

up vote 16 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
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

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

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 at 2:27

Your Answer

 
discard

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.