You ask:
But how can I store the output to the same file for:
find . -name "*.py" -type f -exec grep "something" {} \
You misunderstand. The reason you can't pipe this to anything is that it is not a full command. The closing \
tells your shell to continue reading the command on the next line, which is not what you intend to do here. When you try:
find . -name "*.py" -type f -exec grep "something" {} \ > output.txt
the \
escapes a blank character that, as a result, will be passed as an extra argument to find
, and find
will complain that the command passed to its -exec
option isn't being terminated.
Terminating that command must be done by adding a +
or ;
token, and the ;
token is special to the shell, so it must be escaped or quoted. Additionally, {
and }
are also special in most shells, so they must be escaped or quoted as well:
find . -name "*.py" -type f -exec grep "something" \{} \;
or
find . -name "*.py" -type f -exec grep "something" '{}' ';'
These are valid commands, so you can redirect and pipe their output just fine:
find . -name "*.py" -type f -exec grep "something" \{} \; > output.txt
find . -name "*.py" -type f -exec grep "something" '{}' + | fgrep -v notthesefiles: > output.txt
By the way, I prefer to single-quote arguments if I don't want the shell to interpret any characters in them, even though (as @Kusalananda points out), that is not necessary in this case:
find . -name '*.py' -type f -exec grep 'something' \{} \; > output.txt
For the difference between ;
and +
, try man find
.
+
instead of\;
, it will improve execution time significantly (since it will contatenate arguments prior to execution untilARG_MAX
). – Chris Down Nov 06 '11 at 14:31grep -H
if you want to include the filename of the file in the output. – Steinar Apr 23 '18 at 13:18LC_ALL=C
right beforexargs
to get a lot of extra speed. And you can use a-P6
flag onxargs
to run in parallel with (in this case) 6 processes (feel free to change the number from 6 to something higher or lower, to see what's faster on your machine and on your search). Reference: https://unix.stackexchange.com/questions/131535/recursive-grep-vs-find-type-f-exec-grep-which-is-more-efficient-faster – Michele Piccolini May 22 '20 at 08:24+
instead of\;
will pass multiple files to grep, and if any file in that set contains the text 'something', all those files will pass the test. So it won't do what you want. – Alexander Torstling Nov 17 '20 at 19:37