How can I grep the results of FIND using -EXEC and still output to a file?

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 output.txt file exists, it will be truncated, otherwise it will be created.

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 pathnames that passes the given tests (only the single -name test above). However, if you replace the \; with a +, grep is called with multiple pathnames from find (up to a certain limit).

See question Using semicolon (;) vs plus (+) with exec in find for more on the subject.


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"' {} \;

For the record, grep has --include and --exclude arguments that you can use to filter the files it searches:

grep -r --include="*.py" "something" > output.txt

Tags:

Find